#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] = '\0';
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
的指针之前释放(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);
}
关于c - 为什么我用 C 编写的以下 getString() 函数不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42036516/