简体   繁体   中英

Weird segmentation fault while accessing string array

Sorry to post my project code directly. I've been trying to wrap my head around this weird seg fault which occurs at the line for(j=0; j<100 && *nnames[j] != (char *) NULL; j++) . Isn't it legal to access a char** array this (*arr[]) way ?

    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;

}

If nnames is a pointer to the first element of an array of pointers of type char * then the valid code will look like

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

provided that the last element of the array is a null pointer.

The same is valid for statement

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

that is it has to be rewritten like

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

Also this function

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

     //...

     return names;

}

has undefined behaviour because it returns pointer to the first element of a local array that will be destroyed after exiting the function.

Take into account that if function strsave creates dynamically a copy of the string passed to it as the argument

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

then the program has memory leaks because you do not free canname.

And of course you may write like

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

or even like

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

but the both statements are equivalent to

strcat(new_str,"\n");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM