如何解决如何在不使用C括号的情况下修改字符串文字的内容? 堆栈内存堆内存
免责声明:这是一项家庭作业。
说我有一个这样声明的字符串:
char *string1;
对于我的程序的一部分,我需要将string1设置为另一个字符串string2。我不能使用strcpy或括号。
到目前为止,这是我的代码:
int i;
for(i = 0; *(string2 + i) != '\0'; i++){
*(string1 + i) = *(string2 + i);
}
这会导致分段错误。
根据{{3}}的说法,这是因为string1的声明是这样的:char *string1
,一种避免段错误的解决方法是使用方括号。我不能使用方括号,所以有什么解决方法吗?
编辑:我也被禁止分配更多的内存或声明数组。我不能使用malloc(),falloc()等。
解决方法
您遇到的问题是string2
没有为其分配内存。
您的代码缺少一些细节,但是我认为它看起来像这样:
#include <stdio.h>
int main()
{
char *originalStr = "Hello NewArsenic";
char *newStr;
// YMMV depending on the compiler for this line. Might print (null) for
// newStr or it might throw an error.
printf("Original: %s\nNew: %s\n",originalStr,newStr);
int i;
for (i = 0; *(originalStr + i) != '\0'; i++)
{
*(newStr + i) = *(originalStr + i);
}
printf("Original: %s\nNew: %s\n",newStr);
return 0;
}
TL; DR您的问题
这里的问题是,您试图在没有足够内存的情况下将某些值存储到newStr
中。
解决方案
使用malloc
。
#include <stdio.h>
#include <stdlib.h> // malloc(size_t) is in stdlib.h
#include <string.h> // strlen(const char *) is in string.h
int main()
{
char *originalStr = "Hello NewArsenic";
// Note here that size_t is preferable to int for length.
// Generally you want to be using size_t if you are working with size/length.
// More info at https://stackoverflow.com/questions/19732319/difference-between-size-t-and-unsigned-int
size_t originalLength = strlen(originalStr);
// This is malloc's typical usage,where we are asking from the system to
// give us originalLength + 1 many chars.
// The `char` here is redundant,actually,since sizeof(char) is defined to
// be one by the C spec,but you might find it useful to see the typical
// usage of `malloc`.
// Since malloc returns a void *,we need to cast that to a char *.
char *newStr = (char *)malloc((originalLength + 1) * sizeof(char));
// Your code stays the same.
printf("Original: %s\nNew: %s\n",newStr);
size_t i;
for (i = 0; *(originalStr + i) != '\0'; i++)
{
*(newStr + i) = *(originalStr + i);
}
// Don't forget to append a null character like I did before editing!
*(newStr + originalLength) = 0;
printf("Original: %s\nNew: %s\n",newStr);
// Because `malloc` gives us memory on the stack,we need to tell the system
// that we want to free it before exiting.
free(newStr);
return 0;
}
长答案
什么是C字符串?
在C中,字符串仅仅是字符数组。这意味着对于每个想要拥有的字符,您都需要分配内存。
内存
在C语言中,有两种类型的内存分配-基于堆栈的和基于堆的。
堆栈内存
您可能比您想象的更熟悉基于堆栈的内存。每当声明变量时,就在堆栈上定义它。用括号表示法type array[size_t]
声明的数组也是基于堆栈的。基于堆栈的内存分配的特定之处在于,当您分配内存时,它可能只会持续使用声明它的函数的时间,这可能是您熟悉的。这意味着您不必担心内存停留的时间比实际需要的时间长。
堆内存
现在基于堆的内存分配有所不同,因为它将一直持续到清除为止。这是一种优势:
- 您可以保留在编译时不知道其大小的值。 但是,这是有代价的:
- 堆比较慢
- 完成操作后,您必须手动清除内存。
有关更多信息,请查看this线程。
我们通常使用函数(void *) malloc(size_t)
及其姐妹(void *) calloc(size_t,size_t)
来分配堆内存。要释放系统要求的内存,请使用free(void *)
。
替代品
您也可以使用newStr = originalStr
,但是实际上并不会复制字符串,而只是使newStr
指向originalStr
,我相信您已经知道
其他备注
- 通常,这是一种反模式:
char* string = "literal";
这是一个反模式,因为不能编辑文字,也不能编辑文字。做:
char const* string = "literal";
有关更多信息,请参见this线程。
- 避免在循环中使用
int
。使用size_t
参见this线程。
对于我的程序的一部分,我需要将string1设置为另一个字符串string2。我不能使用strcpy或括号。
也许解决方案就像
string2 = string1
请注意,这会将string2
指针分配为直接指向与string1
相同的内存。有时候这很有用,因为您需要使用string1
来保持字符串的开头,但是还需要另一个指针来使用string2++
这样的字符串来移动字符串。
以一种或另一种方式,您必须将string2
指向您可以访问的内存中的地址。有两种方法可以做到这一点:
-
指向您已经可以通过另一个变量(具有另一个指针变量或
&
运算符的地址)访问的内存。 -
使用
malloc()
或相关功能分配内存。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。