Передача многомерных массивов в C - PullRequest
2 голосов
/ 08 января 2009

Я сейчас пытаюсь выучить C и столкнулся с проблемой, которую не смог решить.

Рассмотрим:

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

#define ELEMENTS 5

void make(char **array, int *array_size) {
    int i;
    char *t = "Hello, World!";

    array = malloc(ELEMENTS * sizeof(char *));

    for (i = 0; i < ELEMENTS; ++i) {
        array[i] = malloc(strlen(t) + 1 * sizeof(char));
        array[i] = strdup(t);
    }
}

int main(int argc, char **argv) {
    char **array;
    int size;
    int i;

    make(array, &size);

    for (i = 0; i < size; ++i) {
        printf("%s\n", array[i]);
    }

    return 0;
}

Я понятия не имею, почему выше не удается прочитать содержимое массива после его создания. Я буквально потратил час, пытаясь понять, почему это не удается, но пришел с пустыми руками. Без сомнения, это что-то тривиальное.

Приветствия

Ответы [ 5 ]

6 голосов
/ 08 января 2009

Вам нужно передать адрес "массива" в функцию. То есть вам нужен чарс ***. Это потому, что вам нужно изменить значение массива, выделив ему память.

РЕДАКТИРОВАТЬ: просто, чтобы сделать его более полным, в объявлении функции необходимо иметь что-то вроде

void make(char ***array, int *array_size)

Тогда вам нужно позвонить, используя

make(&array, &size);

Внутри функции сделать , выделить память с помощью

*array = malloc(ELEMENTS * sizeof(char *));

И соответственно поменяйте местами.

Также, как указывал kauppi, strdup выделит вам память, поэтому вам не нужно выполнять malloc для каждой строки.

5 голосов
/ 08 января 2009

Вот рабочий код:

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

#define ELEMENTS 5

void make(char ***array) {
    char *t = "Hello, World!";

    *array = malloc(ELEMENTS * sizeof(char *));

    int i;
    for (i = 0; i < ELEMENTS; ++i) {
        (*array)[i] = strdup(t);
    }
}

int main(int argc, char **argv) {
    char **array;
    make(&array);

    int i;
    for (i = 0; i < ELEMENTS; ++i) {
        printf("%s\n", array[i]);
        free(array[i]);
    }
    free(array);
    return 0;
}

Как уже сообщали другие - там был неиспользуемый размер, и strdup выделяет память самостоятельно, а потом приятно освободить память ...

4 голосов
/ 08 января 2009

См. Комментарий PolyThinker, который абсолютно точен.

В дополнение к тому, как вы передаете массив, вы должны проверить еще несколько вопросов:

  1. Возможно, вам следует назначить что-то для array_size в make (...)?
  2. strdup (char *) выделяет память, malloc для массива [i] не требуется.
  3. Вы должны освободить всю выделенную память, когда она вам больше не нужна.
3 голосов
/ 08 января 2009

Вы передаете текущее значение массива для создания в виде копии (в стеке). когда вы изменяете массив в make (), вы изменяете только копию, а не фактическую переменную. Попробуйте передать по ссылке с &, или сделайте его символом *** и работайте с * array = ...

0 голосов
/ 08 января 2009

размер объявлен, но ему не назначено значение (что должно произойти в функции make, я полагаю).

...