2012-05-21 3 views
1
#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    void *malloc(size_t size); 
    char *ptr, *retval; 
    ptr = (char *)calloc(10, sizeof(char)); 

    if (ptr == NULL) 
     printf("calloc failed\n"); 
    else 
     printf("calloc successful\n"); 

    retval = realloc(ptr, 5); 

    if (retval == NULL) 
     printf("realloc failed\n"); 
    else 
     printf("realloc successful\n"); 

    free(ptr); 
    free(retval); 
} 

вот мой код возникает ошибка в строке 14, он говоритпреобразование из пустоты * на символ *

недопустимое преобразование из «пустоты *» до «полукокса *»

+4

Это не C++, поэтому не помещайте его как таковой. – Xeo

+0

Можете ли вы переформатировать это, чтобы он читал чище? – octopusgrabbus

+0

@Xeo: Если он был скомпилирован как C, он бы не получил проблему ... Так что C++, вероятно, более уместен ... – Goz

ответ

8

Вы можете просто привязать результат realloc к (char *), как вы делаете с malloc.

retval = (char*)realloc(ptr, 5); 

Как ни странно, то, что вы написали, является совершенно законным кодом «C» ... просто не C++, где вам требуется актерский состав. Поэтому вы также можете попытаться настроить компилятор на компиляцию кода как «C», поскольку вы не делаете никаких C++, и это также решит проблему. Тем не менее вышеупомянутая модификация также совершенно легальная C ... так что будет компилироваться под C++ и C.

Редактировать: Как мягко правильно указывает ваш realloc ptr и сохраняет местоположение указателя в retval, что означает, что ptr, указывая на недопустимую память, и вы НЕ должны ее освобождать. В лучшем случае вы освобождаете одну и ту же память дважды, в худшем случае вы освобождаете память, которая уже освобождена (по realloc). В любом случае это плохо (tm). Так как вы вызываете какое-то серьезное «неопределенное поведение».

+1

ну спасибо за ответы. в любом случае я это сделал :) и извините за теги, так как это был мой первый вопрос, поэтому я не знал, как их использовать;) спасибо в любом случае;) –

+0

@ejazdogar: Если вы нажмете маленький тик под номером до слева от моего поста, тогда вы «принимаете» мой пост;) – Goz

1

Вы не можете освободить указатель twice.Here RetVal и PTR обе точки в том же месте добавить этот код и проверить, прежде чем звонок бесплатный:

printf("%p \n ",ptr); 
printf("%p \n",retval); 

перераспределить сократился размер дэ, но местоположение указателя остается одна и та же. вы можете попробовать это так:

if(ptr == retval) 

/* delete either ptr or retval - just for sake of this programm , Idealy you shouldnt free the the pointer like this as Rightly Suggested by **Goz** in C++/c*/ 

Просто, чтобы сделать его work.otherwise компилируется отлично от GCC, но если запустить это даст грязную трассировку стеки, как вы пытаетесь освободить тот же указатель twice.the базовый вызов прерывания функцией распределения памяти может или не может назначать ему один и тот же указатель .IF вы увеличиваете размер может быть на 30 или 50, это может дать вам другой указатель.

Rgds, Softy

+0

У вас есть хороший момент, но после перераспределения вы абсолютно не должны, когда-либо, освобождать ptr ... он либо указывает на то же место, что и retval, либо уже освобожден! – Goz

+0

да, возможно, это возможно или нет, поэтому эта проверка эквивалентности ptr! – Raulp

+0

, но если они не равны (или даже если они есть), тогда вы не должны освобождать ptr ... поэтому проверка эквивалентности несущественна ... вызов бесплатного на ptr - это ошибка, ожидающая, чтобы это произошло ... – Goz

0

Если вы хотите, чтобы компилировать, использовать C компиляции. Похоже, вы используете компиляцию C++. Он действителен C, но не является допустимым C++. В большинстве компиляторов с использованием строчного расширения .c приведет к тому, что компилятор автоматически использует компиляцию C. .cpp вызовет компиляцию C++, также .C (в верхнем регистре) может вызвать компиляцию C++ (например, в gcc).

1

Другие отметили, что ваш код C скомпилирован как код на C++. Приведение в C не требуется, но требуется в C++. В C++ вы должны использовать векторы (или строку).

Вот некоторые замечания по вашему коду:

  1. Не переобъявить таНос. В том числе stdlib.h сделает это за вас. К счастью, вы успешно выполнили свою декларацию, поэтому она является избыточной (и сбивает с толку кого-то другого, читающего код). Если вы ошиблись в декларации, у вас есть неопределенное поведение.

  2. Не освободите 'ptr', если realloc успешно.

  3. Некоторые люди могут указать, что в некоторых эзотерических системах calloc может не делать то, что вы ожидаете (в частности, для типов указателей и с плавающей запятой). Учитывая, что вы хотите, чтобы ваше динамически распределенное пространство было инициализировано с подходящими значениями, в любом случае излишним вызывать calloc, чем malloc.

Смежные вопросы