为什么我用 C 编写的以下 getString() 函数不起作用?


#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);

这试图做的是…

  1. 分配一个更大的字符串
  2. 将旧字符串复制到新字符串
  3. 使用新字符串
  4. 松开旧绳子

但事实并非如此。问题是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);
}

最新更新