My Avatar

Shilong ZHAO

Are Char Pointer and Char Array Equivalent in C?

2017-01-26 00:00:00 +0100

In case you have any questions or suggestions, you can leave comments HERE . Thanks!

No. They are not.

A student got some problem in a C exercise and cannot run it correctly. The problem is

A string includes sub-strings, made-up of alphabetic and numeric characters, and delimited by the full-stop ‘‘.’’ character. Write the function node_t *splitStr (char *str); which receives such a string as parameter str and it returns the pointer to a list in which each element includes a sub-string defined in a dynamic way.

and her solution is following

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node
{
    char *string;
    struct node *next;
} node_t;

node_t *splitStr(char *str);
node_t *insert(node_t *p,node_t *list);
void printlist(node_t *head);

int main(int argc, const char * argv[]) {
    char *str="a.bb.ccc.dddd.eeeee.fffff";
    node_t *result;
    
    result=splitStr(str);
    printlist(result);
    return 0;
}

node_t *splitStr(char *str) {
    node_t *list = NULL;
    char *p,*q,c;
    
    p=str;
    q=str;
    while(1){
        while (*q != '.'  && *q != '\0'){
            q++;
        }
        c=*q;
        *q='\0';
        node_t *n = malloc(sizeof(node_t));
        n->string = strdup(p);
        list = insert(n, list);
        if(c !='\0'){
            p=q+1;
            q++;
        }
        else{
            break;
        }
    }
    return list;
}

node_t *insert(node_t *n,node_t *list){ 
    if(list == NULL){
        list=n;
        list->next=NULL;
        return list;
    } else {
        n->next=list;
        list=n;
        return list;
    }
}

void printlist(node_t *head){
    if(head==NULL){
        return;
    }
    printf("%s",head->string);
    printf(" -> ");
    printlist(head->next);
}

It’s a good work and the logic seems quite right, but everytime it runs, we get access error, which means we are accessing illegal memory.

The following two declarations have completely different representations in memory:

char *str1 = "fat";
char str2[] = "hat";

In the first delcaration, you cannot do str1[0] = 'c' nor *(str1 + 1) = 'i', or in other words, str1 is a constant; but in the second string you can do both. The reason it that str1 is far away from where the string fat is stored, so str1 + 1 does not points to the second character in the string, but an undefined memory.

So the solution is to change the char *str declaration in main to char str[] and everything will work properly.

A good explanation is here: http://c-faq.com/strangeprob/strlitnomod.html