读取字符串时导致总线错误

时间:2015-02-25 23:30:41

标签: c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
	char *input = (char *)malloc(sizeof(char));
	input = "\0";

	while (1){
		scanf("%s\n", input);

		if (strcmp(input, "0 0 0") == 0) break;

		printf("%s\n",input);
	}

}

我正在尝试读入一串整数,直到输入“0 0 0”。 程序执行scanf线后立即吐出总线错误,我不知道如何修复它。 以下是错误日志。

[1]    59443 bus error

3 个答案:

答案 0 :(得分:4)

您将input设置为指向字符串文字的第一个元素(同时泄漏最近分配的缓冲区):

input = "\0"; // now the malloc'd buffer is lost

然后你尝试修改所说的文字:

scanf("%s\n", input);

这是未定义的行为。你不能写到那个位置。您可以通过删除第一行input = "\0";来解决该问题。

接下来,请注意您只为一个角色分配空间:

char *input = (char *)malloc(sizeof(char));

修复内存泄漏和未定义的行为后,您可以考虑分配更多空间。您需要多少空间来表示,但是您需要足够的空间来包含您想要读取的最长字符串以及空终止符的额外字符。例如,

char *input = malloc(257);

允许您读取最多256个字符的字符串。

答案 1 :(得分:0)

当前的问题,(感谢另一个答案)是你通过将input指向只读数据,然后尝试通过scanf写入它来初始化scanf()错误。 (是的,即使是低位文字“”也是指向存储空字符串的内存区域的指针。)

下一个问题是语义:当strcat()很快覆盖你放在那里的任何内容时,尝试初始化它是没有意义的。但是如果你想要,那么输入[0] ='\ 0'的有效方法是合适的,例如,使用malloc()的循环。

最后,等待机会咬你是一个更深层次的问题:你需要更好地理解sizeof()scanf。您只为一个字符分配足够的空间,然后使用任意长度的字符串超出1-char缓冲区(最多为终端在一行上允许的最大长度。)

粗略的分配将比你需要的分配更多,比如说256个字符,但是{{1}}是一个非常糟糕的功能 - 这使得缓冲区溢出变得非常容易,特别是对于初学者而言。我会留给其他人建议替代方案。

有趣的是,崩溃的类型可以表明你做错了什么。总线错误通常与修改只读内存(仍然是映射页面)有关,例如您正在尝试执行此操作,但是分段违例通常表示通过访问未映射的页面来超出可写内存范围的缓冲区。

答案 2 :(得分:0)

input = "\0";

错了。

'input'是指针,而不是内存。

“\ 0”是字符串,而不是字符。

指定一个新值的指针,该值指向一个包含常量的内存段,因为“\ 0”是常量字符串文字。

现在,当您尝试修改此常量内存时,您将收到预期的总线错误。

在你的情况下,我假设你想用空字符串初始化'input'。 使用

input[0]='\0';

注意0附近的单引号。

下一个问题是malloc:

char *input = (char *)malloc(sizeof(char));

您只为1个字符分配内存。

当用户输入5 0字符+ 0的“0 0 0”时,你会得到缓冲区溢出,可能会破坏一些无辜的变量。

预先分配足够的内存以存储所有用户输入。通常的值是256,8192字节并不重要。

然后,

scanf("%s\n", input);
如果用户输入了大量文本,

仍可能超出缓冲区。使用fgets(buf,limit(如8192),stdin),这将更安全。