我正试图用Kernighan和Ritchie的书来学习C语言"C程序设计语言";。作为一个练习者,我正在尝试编程一个向量乘法器。我目前正在尝试收集两条线,每条线代表一个向量,然后将它们转换为双。在运行程序时,我遇到了分段错误。
如果我注释掉第67行并取消注释第66行(使用mycharcat()
(,则在gdb
中我得到:
Thread 2 received signal SIGSEGV, Segmentation fault. 0x0000000100003bc0 in mycharcat ()
如果我注释掉第66行并取消注释第67行(使用strncat()
(,则在gdb
中我得到:
Thread 2 received signal SIGSEGV, Segmentation fault. 0x00007fff20519552 in ?? ()
解决这个问题的下一步可能是什么?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXLINE 100
#define MAXDOUBLE 20
int mygetline(char s[], int lim)
{
int c, i;
i = 0;
while(--lim > 0 && (c = getchar()) != EOF && c!= 'n')
{
s[i++] = c;
}
if (c == 'n')
{
s[i++] = c;
}
s[i] = ' ';
return i;
}
void mycharcat(char s[], char t)
{
for (; *s != ' '; s++ )
{
;
}
*s = t;
s++;
*s = ' ';
}
char myarray1 [][MAXDOUBLE] = {"", "", ""};
char myarray2 [][MAXDOUBLE] = {"", "", ""};
//int getvec(char *myarray[]);
int getvec(char **myarray)
{
char line[MAXLINE];
strcpy(line, "");
int space_count, i;
char doublechar[MAXDOUBLE];
mygetline(line, MAXLINE);
space_count = 0;
i = 0;
strcpy(doublechar, "");
while(i<strlen(line)){
if (isspace(line[i]) || line[i] == ',' )
{
//printf("space checkedn");
if (isspace(line[i-1])!=1 && line[i-1] != ',' ){
space_count++;
}
i++;
strcpy(doublechar, "");
}
else if (isdigit(line[i]) || line[i] == '.')
{
//mycharcat(myarray[space_count], line[i]);
strncat(myarray[space_count], &line[i], 1);
i++;
}
else
{
printf("Only enter digits, space or comman");
return -1;
}
}
printf("space_count: %dn",space_count);
for (i = 0; i<space_count; i++)
{
printf("myarray[%d]: %sn", i, myarray[i]);
}
return 1;
}
int main()
{
int nline = 0;
while(nline < 2)
{
nline++;
getvec(myarray1);
}
return 0;
}
我怀疑您的程序是否达到了您的目的。让我们看看您的数据和逻辑。
char myarray1 [][MAXDOUBLE] = {"", "", ""};
这是一个N数组的数组,每个数组的大小为MAXDOUBLE
N是1,因为初始值设定项列表是3个字节:三个' '
字符。根据C标准,myarray1
的其余部分将为零填充。
您可以通过打印sizeof(mayarray1)
和sizeof(myarray1[0])
来验证这一点。您可以使用sizeof(mayarray1) / sizeof(myarray1[0])
计算N。
在程序逻辑中,使用写入阵列
strncat(myarray[space_count], &line[i], 1);
但在任何时候都不能确保CCD_ 11小于CCD_。这是一种经过时间考验的解决问题的方法:哪个操作引用了无效位置?因为我看到了space_count++
,我很确定,不需要进一步研究,在某个时刻,您引用了myarray1[1]
,并超出了程序内存空间的限制。
一些可能对你的努力有所帮助的建议:
- 断言您的先决条件断言(3(是你的朋友。在写入数组之前,请断言索引在边界内。在写入指针之前,断言指针指向有效的东西,它不是NULL,并且它位于数组的开头和结尾之间
- 用要使用的类型定义要操作的变量。在您的情况下,您想要一个
double
的数组,所以定义它。然后决定如何填充 - 当读取文本并将其转换为数字时,使用getline(3(一次读取一行(如果您想要的话(,并使用sscanf
我认为,如果你遵循这个计划,你会发现你的程序更容易编写和理解,而且通常你会花更少的时间询问为什么要查看SIGSEGV
消息。