1

I want to have a 2d char array, and when I don't use the struct I can loop through the array and print out the strings. However if I assign the 2d char array to a struct member, I cannot access the array, why?

typedef struct {
    int num;
    char **names;
} test;


test t;
t.num = 2;
char *names[t.num];
char *tmp;
tmp = "test";

names[0] = "something";
strcpy(tmp,names[0]);
strcat(tmp,"appendedtext");
names[1] = tmp;
names[2] = "something else";


t.names = names;
1
  • Can you provide the exact error you are getting? Commented Feb 26, 2011 at 0:33

2 Answers 2

2

You really should be dynamically allocating your arrays here. There are a lot of problems with the things you are trying to do here.

  • Your array is initialized to point to memory on the stack.
  • You are storing pointers to string literals and attempting to modify them.
  • You are accessing memory beyond the bounds of your array.
  • And everything in between.

It just so happens I have some utility functions to dynamically allocate 2-dimensional arrays using a single allocation. Feel free to use them in your code.

static size_t getsize(size_t rows, size_t cols, size_t size)
{
    size_t ptrsize = rows*sizeof(void *);
    if (ptrsize%size != 0)
        ptrsize += size - ptrsize%size;
    return ptrsize + rows*cols*size;
}

static void init2d(void *mem, size_t rows, size_t cols, size_t size)
{
    int i;
    char **ptr = mem;
    char *base = (char *)(ptr + rows);
    size_t rowsize = cols*size;
    size_t ptrsize = rows*sizeof(char *);
    if (ptrsize%size != 0)
        base += size - ptrsize%size;
    for (i = 0; i < rows; i++)
        ptr[i] = base + i*rowsize;
}

void *malloc2d(size_t rows, size_t cols, size_t size)
{
    size_t total_size = getsize(rows, cols, size);
    void *mem = malloc(total_size);
    init2d(mem, rows, cols, size);
    return mem;
}

void *calloc2d(size_t rows, size_t cols, size_t size)
{
    size_t total_size = getsize(rows, cols, size);
    void *mem = calloc(total_size, 1U);
    init2d(mem, rows, cols, size);
    return mem;
}

Then your code would look something like this:

#define MAXWIDTH 100
int num = 3;
test t;
t.num = num;

/* dynamically allocate the memory for t.name */
t.names = calloc2d(t.num, MAXWIDTH, sizeof(char));

/* do your thing here */
const char *tmp = "test";
strcpy(t.names[0], tmp);
strcat(t.names[0], "appendtext"); /* just be careful not to go past MAXWIDTH */

strcpy(t.names[1], tmp);

strcpy(t.names[2], "something else");

/* free the memory that was allocated when done */
free(t.names);    
t.names = NULL;
Sign up to request clarification or add additional context in comments.

Comments

1

shouldn't you alloc memory for your arrays before trying to access them ?

EDIT:

names[2] = "something else" gets you out of index.. you declared only a 2 string array.

Since you said that the memory is declared automatically as a constant, then you should have noticed:

char *tmp;
tmp = "test";

strcpy(tmp, "something"); //something is longer than test

2 Comments

as far as I'm aware the memory is declared automatically as a constant when doing char *s = "something"
It's not that it's longer that's the problem. It's the undefined behaviour invoked by modifying the array backing a string literal. In this case, undefined means segfault.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.