C: Как сохранить массив 2d Char в структуре? - PullRequest
1 голос
/ 26 февраля 2011

Я хочу иметь двумерный массив символов, и когда я не использую структуру, я могу перебирать массив и распечатывать строки.Однако, если я назначаю массив 2d char члену структуры, я не могу получить доступ к массиву, почему?

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;

Ответы [ 2 ]

2 голосов
/ 26 февраля 2011

Вы действительно должны динамически размещать свои массивы здесь. Есть много проблем с тем, что вы пытаетесь сделать здесь.

  • Ваш массив инициализирован, чтобы указывать на память в стеке.
  • Вы храните указатели на строковые литералы и пытаетесь их изменить.
  • Вы обращаетесь к памяти за пределами вашего массива.
  • И все, что между ними.

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

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;
}

Тогда ваш код будет выглядеть примерно так:

#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;
1 голос
/ 26 февраля 2011

разве вы не должны выделять память для своих массивов, прежде чем пытаться получить к ним доступ?

РЕДАКТИРОВАТЬ:

names[2] = "something else" выводит вас из индекса.только массив из 2 строк.

Поскольку вы сказали, что память объявляется автоматически как константа, то вы должны были заметить:

char *tmp;
tmp = "test";

strcpy(tmp, "something"); //something is longer than test
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...