1

我下面的代码有什么问题?

当我通过 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;
}
4

5 回答 5

3

在你的代码中,

 pointerToMyOwnStructPointer = (myIntegers_t**)myOwnStructPointer;

是非常错误的。您需要将其更改为

pointerToMyOwnStructPointer = &myOwnStructPointer;

获得预期的行为。

详细说明,

  • myOwnStructPointer是一个指向类型的指针。
  • pointerToMyOwnStructPointer是一个指向指针的类型。

它们不等价仅仅因为它们都是指针,您不能简单地一种类型的值转换为另一种类型并期望它起作用。演员表是错误的(甚至不需要)。所以,

  • 不要施放
  • 启用编译器警告。

大多数时候,你的编译器至少会通过警告来拯救你。


注意:请参阅为什么不将malloc()and family的返回值转换为C.

于 2015-07-15T11:11:04.133 回答
1

如果您在作业中没有该演员表,将会出现错误或警告

pointerToMyOwnStructPointer = (myIntegers_t**)myOwnStructPointer;

那是因为myOwnStructPointer是指向你的结构的指针,但是pointerToMyOwnStructPointer是指向你的结构的指针,这两种类型是完全不兼容的。

编译器会这样解释它:

+-----------------+ +--------------+ +-- ------+
| pointerToMyOwnStructPointer | -> | 一些地址 | -> | 结构 |
+-----------------+ +--------------+ +-- ------+

因此,当您进行分配然后使用pointerToMyOwnStructPointer它时,会导致未定义的行为,因为它没有指向指针。


这里的教训是,您几乎应该插入类型转换来解决编译器错误或警告,错误和警告的存在是有原因的,警告通常告诉您您正在做一些可能导致未定义行为的可疑行为。

于 2015-07-15T11:15:47.897 回答
0

只是一个改进建议

此外,正确malloc的分配方式是

myIntegers_t * myOwnStructPointer = malloc(sizeof(myIntegers_t));
if (myOwnStructPointer == NULL)
    return 1;

. . .    // else do something with myOwnStructPointer;
于 2015-07-15T11:14:16.297 回答
0

这是我的原始代码,现在在我添加一个“&”标记后它可以工作了。非常感谢您的支持!!

对此代码有任何评论吗?我认为 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;  
}
于 2015-07-15T12:43:57.213 回答
0

回答你的新问题。

正如 Shreevardhan 和 Sourav Ghosh 所述,您应该始终在 c++ 中强制转换 malloc,而永远不要在 c 中强制转换 malloc。

您所有的 void* 实际上都是 myIntegers_t*,所以将它们设为 myIntegers_t*。它既使读者受益,也使编译器能够发现错误。

你所有的 void** 实际上都是 myIntegers_t**。看上面。

除非 a 和 b 的内容是秘密的,否则你不必在释放前将它们设为 0。而且 free 不需要将其参数强制转换为 void*,因为 void* 与所有指针兼容。它只需要由 malloc、calloc 或 realloc 生成的指针。

我认为额外的描述符没有任何帮助,除了可读性之外,然后只需重命名pointerToMyOwnStructPointer。

于 2015-07-16T00:23:56.440 回答