Простой C-код с неприятной ошибкой «несовместимые типы в присваивании» - PullRequest
0 голосов
/ 10 февраля 2009

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

Мой компилятор постоянно говорит мне: "ошибка несовместимых типов в присваивании"

На линии с функцией realloc

Что я делаю не так? Мне кажется, что и "reverse", и результат realloc должны быть указателями на тип char?

Мой код:

int main(){
char  first[]="hello mark", strng='h', reverse[]="";
char* ptr=&first[10];
int i=0;
    while(ptr > (&strng-0xf4240)){
        printf("%c", *ptr--);
        reverse = realloc(reverse, (i++ * sizeof(char)));
        reverse[strlen(reverse)-i] = *ptr;
    }
printf("%s", reverse);
return 0;
}

Спасибо!

EDIT: Извините, я неправильно разместил их как комментарии ниже

Спасибо за помощь, первый и второй комментарий получили! У меня есть необходимые #include, я просто забыл скопировать их в переполнение стека. Вы были правы, теперь я застрял на ненулевой завершенной функции strlen (). Я решу это самостоятельно. Еще раз спасибо!

Я говорил слишком рано, все скомпилировано, но есть логическая ошибка. Цикл while будет выполнен один раз. Тем не менее, последующие циклы по-прежнему не удается, независимо от начального значения i. Строка, которая вызывает сбой, является строкой, которая вызывает realloc

Ответы [ 3 ]

1 голос
/ 10 февраля 2009

Вы не можете перераспределить память, которая не была изначально неправильной. Вы должны объявить reverse как "char *" и начать с malloc.

Это поможет вам, но вам действительно следует подумать о перераспределении по частям, а не по одному байту за раз. О, я не удосужился исправить тот факт, что "реверс", вероятно, не завершается нулем, когда вы пробуете strlen - я оставлю это как упражнение для читателя.

int main(){
char  first[]="hello mark", strng='h';
char* reverse;
char* ptr=&first[10];
reverse = (char*)malloc(1);
reverse[0] = '\0';
int i=0;
    while(ptr > (&strng-0xf4240)){
        printf("%c", *ptr--);
        reverse = (char*)realloc(reverse, (i++ * sizeof(char)));
        reverse[strlen(reverse)-i] = *ptr;
    }
printf("%s", reverse);
return 0;
}
0 голосов
/ 11 февраля 2009

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

Да, определенно верно, поскольку для перераспределения malloc должна иметь некоторую дополнительную информацию о фрагменте памяти, которым вы манипулируете (либо через таблицу размещения блоков, либо хранится в 4 байтах непосредственно перед указателем). Но вы все равно можете написать:

char * ptr1 = malloc(16);
char * ptr2 = ptr1 + 8;
ptr2 = realloc(ptr2,32);

И у вас не будет ошибки компилятора. Тем не менее, вы все равно, вероятно, получите segfault во время выполнения.

Однако есть принципиальное различие в том, как обрабатывает компилятор C

char * tab = "toto";

и

char tab[] = "toto";

В первом случае tab является указателем типа char * и является lvalue, как любая обычная переменная. Он, вероятно, большую часть времени находится в регистре или может быть адресом в куче. Во втором случае tab является массивом, константой и, следовательно, не l-значением. Вероятно, на уровне сборки он заменяется адресом, указывающим на текстовый раздел вашего двоичного исполняемого файла, где находятся данные для строки «toto».

0 голосов
/ 10 февраля 2009

Или:

  • Вы компилируете свой код C с Компилятор C ++. Вот почему он думает вам нужно разыграть пустоту * вернулся на realloc на символ *. преобразование было бы законным в C.

или

  • Вы не смогли включить stdlib.h, поэтому компилятор считает, realloc возвращает int

Редактировать

При повторном чтении вашего кода реальная проблема заключается в том, что вы присваиваете массив, который не может появляться в LHS присваивания (не является lvalue). Хорошо, что ты принял другой ответ. У него есть хороший совет.

...