Возвращаемое значение 3221225477 происходит, когда я использую указатель для структурирования указателя в коде
Что не так в моем коде ниже?
Там нет никаких ошибок или предупреждений, когда я компилирую его компилятором Dev C++. Но после запуска моей программы возникает ошибка выполнения и следующий текст возвращаемого значения:
Процесс завершен через 5,1 секунды с возвращаемым значением 3221225477
Нажмите любую клавишу для продолжения.,,
Есть идеи, что не так?
Когда я использую функцию отладки, возникает ошибка в этой строке:
printf("Value of (*pointerToMyOwnStructPointer)->a = %d\n", (*pointerToMyOwnStructPointer)->a);
Мой код:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int a;
int b;
}myIntegers_t;
int main (void)
{
myIntegers_t *myOwnStructPointer = NULL;
myIntegers_t **pointerToMyOwnStructPointer = NULL;
myOwnStructPointer = (myIntegers_t*)malloc(sizeof(myIntegers_t));
if (myOwnStructPointer > 0)
{
myOwnStructPointer->a = 2;
myOwnStructPointer->b = 8;
printf("Value of myOwnStructPointer->a = %d\n", myOwnStructPointer->a);
printf("Value of myOwnStructPointer->b = %d\n", myOwnStructPointer->b);
pointerToMyOwnStructPointer = (myIntegers_t**)myOwnStructPointer;
printf("\n");
printf("Value of (*pointerToMyOwnStructPointer)->a = %d\n", (*pointerToMyOwnStructPointer)->a);
printf("Value of (*pointerToMyOwnStructPointer)->b = %d\n", (*pointerToMyOwnStructPointer)->b);
}
else
{
return -1;
}
return 0;
}
5 ответов
В вашем коде,
pointerToMyOwnStructPointer = (myIntegers_t**)myOwnStructPointer;
очень неправильно. Вы должны изменить это на
pointerToMyOwnStructPointer = &myOwnStructPointer;
чтобы получить ожидаемое поведение.
Разрабатывать,
myOwnStructPointer
указатель на типpointerToMyOwnStructPointer
является указателем на указатель на тип.
они не эквивалентны. Просто потому что они оба указатели, вы не можете просто привести значение одного типа к другому и ожидать, что это сработает. Актерский состав неправильный (и даже не обязательный). Так,
- Не бросать
- Включить предупреждения компилятора.
В большинстве случаев ваш компилятор спасет вас, по крайней мере, с помощью предупреждения.
Примечание: пожалуйста, посмотрите, почему бы не бросить возвращаемое значение malloc()
и семья в C
,
Там были бы ошибки или предупреждения, если у вас не было этого приведения в назначении
pointerToMyOwnStructPointer = (myIntegers_t**)myOwnStructPointer;
Это потому что myOwnStructPointer
это указатель на вашу структуру, но pointerToMyOwnStructPointer
это указатель на указатель на вашу структуру, и эти два типа полностью несовместимы.
Компилятор интерпретирует это так:
+ ----------------------------- + + -------------- + + -------+ | pointerToMyOwnStructPointer | -> | какой-то адрес | -> | структура | +-----------------------------+ +--------------+ +------- +
Поэтому, когда вы делаете свое назначение, а затем используете pointerToMyOwnStructPointer
это приводит к неопределенному поведению, так как не указывает на указатель.
Урок здесь заключается в том, что вы почти никогда не должны вставлять приведение типов для решения ошибок или предупреждений компилятора, ошибки и предупреждения существуют по определенной причине, а предупреждения часто говорят вам, что вы делаете что-то подозрительное, что может привести к неопределенному поведению.
Это был мой оригинальный код, и теперь он работает после того, как я добавил один знак "&". Большое спасибо за вашу поддержку!
Есть комментарии по поводу этого кода? Я думаю, что есть приведение к возвращаемому значению функции malloc... это проблема?
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define FAILURE 0
typedef struct{
int a;
int b;
}myIntegers_t;
void * open(void);
int close(void ** pointerToMyOwnStructPointer );
void main(void)
{
void * myVoidParameter;
if(myVoidParameter = open())
{
printf("\n\nPORT OPENED SUCCESSFULLY!!\n\n");
myIntegers_t ** pointerToMyVoidParameter = (myIntegers_t**)&myVoidParameter;
printf("\n");
printf("Value of pointerToMyVoidParameter->a = %d\n", (*pointerToMyVoidParameter)->a);
printf("Value of pointerToMyVoidParameter->b = %d\n", (*pointerToMyVoidParameter)->b);
if(close(&myVoidParameter))
{
printf("\n\nPORT CLOSED SUCCESSFULLY!!\n");
}
else
{
printf("\n\nFAILURE IN PORT CLOSING!!!\n");
}
}
else
{
printf("\n\nFAILURE IN PORT OPENING!!!\n");
}
}
void * open(void){
myIntegers_t *myOwnStructPointer = (myIntegers_t*)malloc(sizeof(myIntegers_t));
if (myOwnStructPointer)
{
myOwnStructPointer->a = 2;
myOwnStructPointer->b = 8;
printf("\n");
printf("Value of myOwnStructPointer->a = %d\n", myOwnStructPointer->a);
printf("Value of myOwnStructPointer->b = %d\n", myOwnStructPointer->b);
return myOwnStructPointer;
}
else
{
return NULL;
}
}
int close(void ** pointerToMyOwnStructPointer ){
int result = OK;
myIntegers_t ** descriptor = (myIntegers_t**)pointerToMyOwnStructPointer;
if(descriptor == NULL || *descriptor == NULL)
{
return FAILURE;
}
printf("\n");
printf("Value of descriptor->a = %d\n", (*descriptor)->a);
printf("Value of descriptor->b = %d\n", (*descriptor)->b);
(*descriptor)->a = 0;
(*descriptor)->b = 0;
free((void*)*descriptor);
*pointerToMyOwnStructPointer = NULL;
return result;
}
Ответьте на свой новый вопрос.
Вы должны всегда приводить malloc в C++ и никогда не приводить malloc в c, как уже было сказано Shreevardhan и Sourav Ghosh.
Все ваши пустоты * на самом деле myIntegers_t*, поэтому сделайте их myIntegers_t*. Это выгодно как для читателя, так и позволяет компилятору обнаруживать ошибки.
Все ваши пустоты ** на самом деле myIntegers_t**. Смотри выше.
Если содержимое a и b не является секретным, вам не нужно устанавливать их в 0 перед освобождением. И для free не требуется указывать аргумент void *, поскольку void * совместим со всеми указателями. Нужно только, чтобы указатель был сделан malloc, calloc или realloc.
Я не думаю, что дополнительный дескриптор помогает, кроме, возможно, читабельности, но затем просто переименуйте pointerToMyOwnStructPointer.
Только предложение по улучшению
Кроме того, правильный malloc
способ распределения будет
myIntegers_t * myOwnStructPointer = malloc(sizeof(myIntegers_t));
if (myOwnStructPointer == NULL)
return 1;
. . . // else do something with myOwnStructPointer;