为什么我在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] = '\0';
return inputString;
}
int main()
{
char* str;
str = getString();
printf("%s", str);
}
我写了这个C程序来获取一个字符串作为C中的用户输入并将其存储在一个可动态调整大小的数组中。但是,每次运行此程序时,它都会崩溃。 我经历了这个程序的类似实现,但不能准确找出我的代码有什么问题为什么我在C中写的下面的getString()函数不起作用?
问题在这里。
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
的记忆。
你想要的是free(inputString)
,旧存储器,复制newString
的指针前。
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
不是空终止。否则,它会读取字符串末尾的垃圾。
strncpy
不是特别安全,它不会在它停止复制时终止,但是对于这个特定的实例,您将在终止时终止它是正常的。
接下来,这是没有必要的。它可以通过realloc
完成。这会增大,缩小或重新分配内存,并在必要时进行复制。
capacity *= 2;
inputString = realloc(inputString, capacity * sizeof(char));
if(inputString == NULL) {
fprintf(stderr, "Reallocation failed.\n");
exit(1);
}
'inputString'在循环结束之前不是空终止的;使用'strcpy()'是不可靠的。使用'memmove()'或'memcpy()'会更合适。而'oldptr = realloc(oldptr,newsize);'meme是等待中的内存泄漏 - 你应该有'newptr = realloc(oldptr,newsize); if(newptr!= 0)oldptr = newptr;其他{...处理错误...}为了安全。 –
@JonathanLeffler谢谢,我知道我错过了什么。 'memcpy'和'strncpy'在这里有什么优势吗?如果我在'realloc'错误处理上吝啬一点,那么你会原谅我,这是它自己的主题。 – Schwern
这将是微不足道的,但是; 'strncpy()'必须计数并检查空字节(它不会找到),而'memcpy()'只需要计数。 –
你使用调试器吗?这是调试这些问题的方法(并且作为最后的手段在Stackoverflow上发布)。 – kaylum
'* buffer = getchar();'查看你的代码来回答:'buffer'指向哪里?试试'char buffer = getchar();' – kaylum
@kalyum试过了,仍然没有用 – Sahil