#include <stdio.h>
char* getString()
{
char buffer;
int size = 0;
int capacity = 1;
char* inputString = (char*)malloc(capacity*sizeof(char));
char* newString;
while(1)
{
buffer = getchar();
if(buffer == 'n')
break;
if((capacity-1) <= size)
{
capacity *= 2;
newString = (char*)malloc(capacity*sizeof(char));
int i;
for(i = 0; i < size; i++)
newString[i] = inputString[i];
inputString = newString;
free(newString);
}
inputString[size] = buffer;
size++;
}
inputString[size] = ' ';
return inputString;
}
int main()
{
char* str;
str = getString();
printf("%s", str);
}
我编写这个C程序是为了获得一个字符串作为C中的用户输入,并将其存储在一个可动态调整大小的数组中。然而,每次我运行这个程序时,它都会崩溃。我经历了这个程序的类似实现,但无法完全弄清楚我的代码出了什么问题
问题就在这里。
capacity *= 2;
newString = (char*)malloc(capacity*sizeof(char));
int i;
for(i = 0; i < size; i++)
newString[i] = inputString[i];
inputString = newString;
free(newString);
这试图做的是…
- 分配一个更大的字符串
- 将旧字符串复制到新字符串
- 使用新字符串
- 松开旧绳子
但事实并非如此。问题是inputString = newString
意味着inputString
指向newString
的内存。当你选择free(newString)
时,那也是inputString
的内存。
相反,在复制newString
的指针之前,您需要的是旧内存free(inputString)
。
capacity *= 2;
newString = (char*)malloc(capacity*sizeof(char));
int i;
for(i = 0; i < size; i++)
newString[i] = inputString[i];
free(inputString);
inputString = newString;
一些注意事项。
您应该从至少2的容量开始,因为容量为1的字符串只能容纳一个空字节。
使用strncpy
可以更好地进行字符串复制。
capacity *= 2;
newString = (char*)malloc(capacity*sizeof(char));
strncpy( newString, inputString, size );
free(inputString);
inputString = newString;
尽管newString
足够大,可以容纳inputString
的内容,但我们仍然需要使用有限制的strncpy
,因为inputString
不是null终止的。否则,它将从字符串末尾读取垃圾。
strncpy
不是特别安全,当它停止复制时,它不会null终止,但对于这个特殊的实例,你会在结束时null终止,这很好。
接下来,这一切都是不必要的。它可以用realloc
来完成。这会增加、缩小或重新分配内存,并在必要时进行复制。
capacity *= 2;
inputString = realloc(inputString, capacity * sizeof(char));
if( inputString == NULL ) {
fprintf(stderr, "Reallocation failed.n");
exit(1);
}