2015-04-30 3 views
0

Извините, что внесите мой код проекта напрямую. Я пытался обмануть эту странную сегрегатную ошибку, которая возникает на линии для (j = 0; j & * nnames [j]! = (Char *) NULL; j ++). Разве это не законно для доступа к массиву char ** (* arr [])?Видимая ошибка сегментации при доступе к строковому массиву

char** nnames = getcannames(); 
    char * new_str ; 

    int j =0, len=0; 
    ////////////////SEG FAULT HERE ////////////////// 
    for(j=0; j<100 && *nnames[j] != (char *) NULL; j++){ 
     len = len + strlen(nnames[j]); 

    } 
    if((new_str = (char*) malloc(len + 3)) != NULL){ 
     new_str[0] = '\0'; // ensures the memory is an empty string 
     int i=0;  
     //setbuf(client_reply, NULL); 
     for(i=0; i<7; i++){ //fix this, garbage values after index 68 
      if(*nnames[i] == (char *) NULL) break; 

      char *canname = strsave(nnames[i]); 


      if((find_newline = strchr(canname, NEWLINE)) != NULL) 
       *find_newline = EOS; 
      if(strcmp(canname, "!") != 0){ 
       strcat(new_str, canname); 
       strcat(new_str, "\n"); 
      } 

      //strcat(new_str, "\n\n"); 
     } 
     strcat(new_str,"\n\0"); 
     printf("%s", new_str); 
     //strcpy(new_str, buf); 
     buf = new_str; 

    } else { 
     perror("malloc failed!\n"); 
     // exit? 
    } 


char** getcannames(){ 
    //INITIALIZE 
    char *names[100]; 
    int i; 
    for(i=0; i<100; i++){ 
     names[i] = strsave("\0"); 
    } 
    int namespos = 0; 

    struct sym_list *sp; 
    for(sp = Head.s_next; 
    sp != (struct sym_list *) NULL; 
    sp = sp->s_next) 
    { 
    if(getcannameindex(names, sp->s_sym.v_value) == -1){ 
     //strcpy(names[namespos++], sp->s_sym.v_name); 
     names[namespos++] = strsave(sp->s_sym.v_value); 
    } 
    } 
    return names; 

} 
+0

'возвращать имена;': 'names' недействительна во внешней области, поскольку это локальная переменная. – BLUEPIXY

+0

@BLUEPIXY, 'names' не используется вне области видимости. – Himanshu

+0

@ Химаншу 'char ** nnames = getcannames();' ?? – BLUEPIXY

ответ

4

Если nnames является указателем на первый элемент массива указателей типа char * то правильный код будет выглядеть

for (j = 0; j < 100 && nnames[j] != NULL; j++){ 
     len = len + strlen(nnames[j]); 

при условии, что последний элемент массива является пустым указателем ,

То же самое справедливо для постановки

if(*nnames[i] == (char *) NULL) break; 

, который он должен быть переписан как

if (nnames[i] == NULL) break; 

Кроме того, эта функция

char** getcannames(){ 
    //INITIALIZE 
    char *names[100]; 

    //... 

    return names; 

} 

имеет неопределенное поведение, потому что она возвращает указатель на первый элемент локального массива, который будет уничтожен после выхода из функции.

Примите во внимание, что если функция strsave создает динамически копию строки, переданной ей в качестве аргумента

char *canname = strsave(nnames[i]); 

тогда программа имеет утечку памяти, потому что вы не бесплатно canname.

И, конечно, вы можете написать, как

strcat(new_str,"\n\0"); 

или даже как

strcat(new_str,"\n\0\0\0\0"); 

, но оба утверждения эквивалентны

strcat(new_str,"\n"); 
+0

Здесь 'names [namespos ++] = strsave (sp-> s_sym.v_value);' еще больше может произойти утечка памяти. – alk

Смежные вопросы