我正在编写一个 C 程序来查找用户输入中最长的一行,并打印该行的长度和该行本身。它成功地计算了字符数,但无法预料地无法存储行本身。也许我误解了 C 的内存管理,有人可以纠正我。
编辑:后续问题:我现在明白 dummy
字符后面的 block 是未分配的,因此打开了计算机可以对它们执行任何操作的范围,但是为什么某些字符的存储是否仍然有效?在我提到的第二个例子中,程序将字符存储在“未分配” block 中,即使它“不应该”。为什么?
变量:
getchar()
存储在c
每次我getchar()
i
是我getchar()
来自 的当前行的长度(到目前为止)
longest_i
是目前最长的行的长度twostr
指向两个字符串中第一个的开头:第一个为当前行,第二个为迄今为止最长的行。当发现一行最长时,将其复制到第二个字符串中。如果 future 的一行更长,它会覆盖第二个字符串的某些部分,但这没关系,因为我不会再使用它了——第二个字符串现在将从更靠右的位置开始。dummy
给twostr
一个指向的地方
这是我可视化程序变量使用的内存的方式:
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|\n| 7|11|15|c |u |r |r |e |n |t |\0|e |s |t |\0|p |r |e |v |l |o |n |g |e |s |t |\0|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
真实陈述:
&c == 11
&i == 12
&longest_i == 13
&twostr = 14
&dummy = 15
程序:
#include <stdio.h>
int main()
{
char c = '\0';
int i, longest_i;
char *twostr;
longest_i = i = 0;
char dummy = '\0';
twostr = &dummy;
while ((c=getchar()) != EOF)
{
if (c != '\n')
{
*(twostr+i) = c;
i++;
}
else
{
*(twostr+i) = '\0';
if (i > longest_i)
{
longest_i = i;
for (i=0; (c=*(twostr+i)) != '\0'; ++i)
*(twostr+longest_i+1+i) = c;
}
i = 0;
}
}
printf("length is %d\n", longest_i);
for (i=0; (c=*(twostr+longest_i+1+i)) != '\0'; ++i)
putchar(c);
return 0;
}
从*(twostr+longest_i+1))
到'\0'
不可预测。示例:
输入:
longer line
line
输出:
length is 11
@
输入:
this is a line
this is a longer line
shorter line
输出:
length is 21
this is a longer lineÔÿ"
最佳答案
您实际上并没有分配任何内存来写入!
char dummy = '\0'; // creates a char variable and puts \0 into it
twostr = &dummy; // sets twostr to point to the address of dummy
在此之后,您只需写入由 dummy 预留的 char 之后的内存,并覆盖 who-knows-what。
在这种情况下,最简单的解决方法是使 dummy 成为一个指向 char 的指针,然后 malloc 一个缓冲区以用于您的字符串(使其比您期望的最长字符串长!)
例如,下面的 buffer
将指向 256 字节(在大多数系统上)的内存,允许字符串长达 255 个字符(因为您有空终止符 (\0) 来存储最后)。
char * buffer = (char *)malloc(sizeof(char) * 256);
编辑:这将从堆中分配内存,稍后您应该在完成后通过调用 free(buffer);
释放它。另一种方法是按照 Anders K 的解决方案用尽堆栈上的空间。
关于C:使用指针作为字符串:不可预知的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8441766/