字符串数组的分段错误

时间:2010-11-30 16:15:01

标签: c string segmentation-fault

我遇到了一些字符串数组的问题,这些字符串似乎正在侵入一个保留的内存空间。代码太大,无法在此发布,因此我将发布以下重要部分:

int main (  ){

 int i = 0, j = 0, k = 0, count = 0, numLinhas = 0, l = 0;
 char string[100][100];
 char line [17];
 char str[4];
 char str1[5];
 char str2[4];
 char str3[4];

 FILE *p;
 p = fopen("text.txt", "r");
 while(fgets(line, sizeof line, p)!=NULL){
  printf("%s", line);
  strncpy(string[i], line, 17);
  i++;
  numLinhas++; 
  }  
  fclose(p);
  char *temp[numLinhas]; 

之后它会进入一个循环,在string [i]中存储文件中包含的语句的含义。 for和三个例子的开头如下所示:

    for (i = 0; i<numLinhas; i++){
    sscanf( string[i], "%s %s %s %s" ,str1, str,str2, str3);
    if(str[0]=='0' && str[1] == '0' && str[2]!= 'd') {
    temp[i] = "NOP";
    count++;
    }
    if(str[0]=='0'&& str[1] == '6' && str[2]!= 'd') {
    sprintf(temp[i],"%s,%s" , "MVI B", str2);
    count = count+2;
    }

    if(str[0]=='0'&& str[1] == '7' && str[2]!= 'd') {
    temp[i] = "RLC";
    count++;
    }

错误是偶然的 - 它并不总是发生。它通常发生在调用sprintf时。 没错!以下是我正在加载的txt文件作为示例:

0000 21a 11r 00r
0003 7Ea
0004 21a 12r 00r
0007 46a
0008 80a
0009 21a 13r 00r
000C 77a
000D 3Ea 01a
000F 3Da
0010 76a
0011 0Ad
0012 03d
0013 01d

刚看到新的东西。这是我得到的编译窗口:

marcos@john:~/Desktop$ ./paraler
0000 21a 11r 00rValor de l: 16

Valor de l: 1
0003 7Ea
Valor de l: 9
0004 21a 12r 00rValor de l: 16

Valor de l: 1
0007 46a
Valor de l: 9
0008 80a
Valor de l: 9
0009 21a 13r 00rValor de l: 16

Valor de l: 1
000C 77a
Valor de l: 9
000D 3Ea 01a
Valor de l: 13
000F 3Da
Valor de l: 9
0010 76a
Valor de l: 9
0011 0Ad
Valor de l: 9
0012 03d
Valor de l: 9
0013 01d
Valor de l: 9
string:0000 21a 11r 00r
string:

string:0003 7Ea

string:0004 21a 12r 00r
string:

string:0007 46a

string:0008 80a

string:0009 21a 13r 00r
string:

string:000C 77a

string:000D 3Ea 01a

string:000F 3Da

string:0010 76a

string:0011 0Ad

string:0012 03d

string:0013 01d

Segmentation fault

奇怪的是我得到了一些字符串数组的空格......是否与错误有关?

3 个答案:

答案 0 :(得分:1)

在调用temp[i]之前,您是否为每个sprintf分配内存?如果没有,那就是你的问题。

if (!strncmp(str, "06", 2) && str[2] != 'd')
{
  temp[i] = malloc(5 + strlen(str2) + 2);  // Thanks, philippe
  if (temp[i])
    sprintf(temp[i], "%s,%s", "MVI B", str2);
}

虽然现在您必须跟踪temp分配了malloc的哪些元素,以便稍后释放它们。

修改

在程序结束时,您可以循环遍历temp数组,并根据上面字符串的前导部分检查每个元素的内容,如果它们匹配,则使用{{1}取消分配该元素}:

free

对于分配了“NOP”或“RLC”的数组元素,您不需要这样做;在这些情况下,您只需将字符串文字的地址复制到数组元素即可。没有为这些元素分配新的内存,因此您不必担心取消分配它们。

答案 1 :(得分:0)

我立即看到一些问题:

编辑第一个点可能不适用于您的环境,但您应该牢记这一点

  • 您正在尝试从一个整数创建char *temp[numLinHas],该整数的值将在运行时确定。这在C99中是允许的,或者可以通过编译器扩展提供,但在较旧的C标准中,必须在编译时知道数组大小。您的代码可能真的这样做:

    int numLinHas = 0;
    char *temp[numLinHas];
    
  • 另一个问题是当你执行sprintf时,你试图复制到temp中的某些内容而不为存储字符串的指针分配内存。

答案 2 :(得分:0)

if(str[0]=='0'&& str[1] == '6' && str[2]!= 'd') {
    /* allocate memory to store instruction - to be freed later */  
    temp[i] = malloc(5 + strlen(str2) + 2); /* +2 for the comma */
    sprintf(temp[i],"%s,%s" , "MVI B", str2);
    count = count+2;
    }

当遇到以06开头并且没有以d结尾的助记符时会出现问题; sprintf()写入未分配的区域,因为temp [i] 未初始化。你应该分配一些空间来存储sprintf的结果。