访问字符串数组时出现奇怪的分段错误

时间:2015-04-30 10:20:23

标签: c arrays

很抱歉直接发布我的项目代码。我一直试图绕过这个奇怪的seg故障,这个故障出现在行(j = 0; j< 100& * nnames [j]!=(char *)NULL; j ++) 即可。以(* arr [])方式访问char **数组是否合法?

    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;

}

1 个答案:

答案 0 :(得分: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");