Динамическое выделение char** в C

У меня есть тип даты, определенный как typedef char* DateTime; формат "дд/мм/гггг-чч:мм", например. "08.08.2012-12:00"

и я хочу выделить n строк, которые являются «датами». Что не так со следующим?

    DateTime*  dates = (DateTime* ) malloc(sizeof(char*) * n);  
for (int i = 0; i <= n; i++) {
    dates[i] =  malloc(sizeof(char)*16);
    if (dates[i] == NULL) {
        free(dates);

        return NULL;
    }
}

person Jenny B    schedule 09.08.2012    source источник
comment
Чтобы сделать код более читабельным, вы должны использовать sizeof(DateTime *) при первом вызове malloc. Или, что еще лучше, поскольку это строки, вообще не создавайте typedef, а везде используйте простые char *.   -  person Some programmer dude    schedule 09.08.2012
comment
Кроме того, две большие ошибки, которые я вижу, заключаются в том, что вы выполняете цикл от одного ко многим и выделяете один к маленькому для фактической строки даты. Если есть что-то еще, что не так, вы должны быть более конкретными, чем просто спрашивать, что не так.   -  person Some programmer dude    schedule 09.08.2012
comment
Писать malloc(sizeof(char*)) вместо malloc(sizeof(*dates)) не очень хорошая идея. Кастинг возврата malloc тоже неверен. stackoverflow.com/questions/605845 /   -  person Eregrith    schedule 09.08.2012


Ответы (4)


for (int i = 0; i <= n; i++) {
                   ^

В C массивы начинаются с 0, поэтому dates[n] недоступны. Отбросьте =.

person cnicutar    schedule 09.08.2012

Помимо ответов @Dan и @cnicutar (оба верны), обратите внимание, что строковый литерал «08/08/2012-12:00» содержит 17 символов (а не 16< /эм>). Хотя длина строки составляет 16, она содержит 16 символов, которые вы видите, ПЛЮС символ '\ 0' в конце, который служит терминатором. Кроме того, sizeof(char) равен единице по определению. Наконец, идиоматический способ выделения памяти с помощью malloc:

DateTime *dates = malloc(n * sizeof *dates);
person Happy Green Kid Naps    schedule 09.08.2012

В дополнение к ответу cnicutar есть и это:

В случае, если это условие верно:

if ( dates[i] == NULL )

вы вызываете только free для всего массива и не освобождаете элементы до i в массиве. Это может привести к значительной утечке памяти

person Dan F    schedule 09.08.2012

Как было указано как мной в комментарии, так и другими, петля

for (int i = 0; i <= n; i++) {

зацикливается один раз ко многим.

Другая проблема заключается в следующем:

dates[i] =  malloc(sizeof(char)*16);

Фактическая строка состоит из 16 символов, но поскольку для строк в C требуется дополнительный символ завершения ('\0'), вам нужно выделить на один символ больше, что означает, что вы должны умножить на 17.

И, как заметил Дэн Ф., у вас также есть потенциальная утечка памяти.

Две самые большие проблемы — это зацикливание и выделение памяти, так как это вызывает так называемое неопределенное поведение при перезаписи нераспределенной памяти.

person Some programmer dude    schedule 10.08.2012