2010-11-30 47 views
0

我遇到了一些似乎侵入了内存预留空间的字符串数组问题。该代码太大,张贴在这里,所以我会后下面的重要组成部分:使用字符串数组的分段错误

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 (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 

刚刚看到了一些新东西。这里的编译窗口我越来越:

[email protected]:~/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 

奇怪的是,我得到的字符串数组的一些空的空间......它有什么关系的错误?

+0

您是否尝试过在调试器中运行代码? – nmichaels 2010-11-30 16:17:58

+0

第1步将用安全snprintf替换不安全的sprintf。 – 2010-11-30 16:19:30

+0

请做一些关于你的代码格式化。第二个钻头的缩进看起来很糟糕。 – JeremyP 2010-11-30 16:26:34

回答

0

有一些问题,我立刻看到:

编辑第一点可能并不适用于您的环境,但你应该记住它

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

    int numLinHas = 0; 
    char *temp[numLinHas]; 
    
  • 的另一个问题是,当你做sprintf,您正试图复制的东西在temp而无需为指针存储字符串分配内存。

1

是否在拨打sprintf之前为每个temp[i]分配内存?如果不是,那就是你的问题。

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阵列和检查每个元素的内容对您的字符串的前导部分上面,如果他们匹配,使用解除对其元free

for (i = 0; i < numLinhas; i++) 
{ 
    if (strcnmp(temp[i], "MVI B", strlen("MVI B")) == 0) 
    free(temp[i]); 
} 

你并不需要为被分配“NOP”或“RLC”数组元素做到这一点;在这些情况下,只需将字符串文字的地址复制到数组元素。没有新的内存分配给这些元素,所以你不必担心释放它们。

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的结果。