【问题标题】:Storing using malloc() or realloc() and printing data in C [closed]使用 malloc() 或 realloc() 存储并在 C 中打印数据 [关闭]
【发布时间】:2014-01-07 07:05:50
【问题描述】:

有人可以告诉我代码有什么问题吗?抱歉,如果我是新手,但我很长一段时间都在努力解决这个问题。我正在尝试从用户那里获取输入,然后打印这些值。下面的代码只是一个例子。

我尝试运行代码,但出现运行时错误。有人可以帮忙吗?

#include <stdio.h>
#include <stdlib.h>

typedef struct poly
{
    int kill;
    float bill;
    char katana[50];
} koly;
 typedef koly* terma;

int main()
{
        int count = 0;
        terma ren;
        ren = (terma)malloc(sizeof(koly));
        ren = (terma)realloc(6*sizeof(koly));
        printf("We can store now:\n\n");
        while(++count<= 2)
        {
            scanf("%d",ren->kill);
            scanf("%f",ren->bill);
            scanf("%s",ren->katana);
        }
        while(++count<= 2)
        {
            printf("\n%d\n",ren->kill);
            printf("\n%f\n",ren->bill);
            printf("\n%s\n",ren->katana);
        }
}

【问题讨论】:

  • 什么运行时错误?
  • realloc : 两个参数
  • 各位大神,投出malloc/realloc的返回值的撒旦做法变得更糟了。 malloc & co 返回void *一个指针,你正在投射它。 不要,尤其是使用您的typedef,这会掩盖您实际上在做什么
  • 不确定为什么要重新分配?看来您只阅读 2 条记录 (` ++count

标签: c malloc scanf dynamic-memory-allocation realloc


【解决方案1】:

关于你的错误:

scanf("%d",ren->kill);
scanf("%f",ren->bill);

这些应该是指针,所以更正的版本是:

scanf("%d",&ren->kill);
scanf("%f",&ren->bill);

另外,realloc 需要 2 个参数,这与 malloc 不同。第一个应该是指向要重新分配的地址的指针,第二个应该是新的大小。所以:

ren = realloc(ren, 6 * sizeof(koly));



关于您的代码,我还有两件事要说。首先:没有必要在 C 中强制转换 malloc 的返回值(并且不赞成)。此外,切勿将scanf"%s" 格式说明符一起使用。这是非常不安全的,很容易导致崩溃甚至更糟。最好的方法是使用fgets,所以scanf("%s",ren-&gt;katana);会变成这样:

fgets(ren->katana, sizeof(ren->katana), stdin);

编辑: 以下是我对为什么应该避免转换 malloc/realloc 的返回值的解释:

这不是真的,因为它是;这是因为在 C 中这样做是不好的做法。由于 void* 类型会自动转换为任何指针类型,因此类型转换是多余的,代码可读性较差(IMO),并且使更改更加困难。例如,以你的情况为例:

ren = (terma)malloc(sizeof(koly));

我个人会这样重写这一行:

ren = malloc(sizeof(*ren));

这允许轻松更改ren 的类型。如果将ren 更改为另一种数据类型(例如int*struct sockaddr_in* 或其他任何类型),它将自动工作。您不需要更改演员表中的类型或sizeof() 中的类型。两者都将自动适用于新类型。对于数组,它的工作原理是一样的:

int* myArr = malloc(42 * sizeof(*myArr));

如果我希望 myArr 保存一个包含 42 个 floats 的数组,那么更改很简单:

float* myArr = malloc(42 * sizeof(*myArr));

注意:在 C++ 中,类型转换是必需的,因为它不会自动将 void* 转换为其他指针类型,但是当你有 new 时,你真的不应该在 C++ 中使用 malloc 等(加上这是一个 C 问题,而不是 C++)。

【讨论】:

  • 嗯,谢谢大家的意见,我很感激。虽然我还有一个问题。为什么对malloc的返回值进行类型转换是错误的?
  • @user3134098 查看我的编辑
【解决方案2】:

void *realloc(void *ptr, size_t size);

realloc 有两个参数,原型如上,你在代码中遗漏的是给出你想要重新分配内存的指针。

你必须使用,ren = (terma)realloc(rem, 6*sizeof(koly));

另一个错误是你在scanf函数中漏掉了&运算符,应该是scanf("%d",&ren->kill);

而且它不是运行时错误,您是否正确编译了代码...?

【讨论】:

    【解决方案3】:

    Realloc() 有两个参数。它是如何编译的?

    ren = (terma)realloc(ren,6*sizeof(koly));
    

    您还需要更正 scanf:

    scanf("%d",&ren->kill);
    scanf("%f",&ren->bill);
    

    但请注意:您正在覆盖您唯一的一个对象。

    【讨论】:

    • 为什么我会完全覆盖主题?代码(当然是更正的版本)不应该将输入存储到结构的各个成员吗?还说会发生覆盖,这会导致在堆上分配内存时出现一些错误吗?
    • @user3134098 因为您正在运行代码以在while循环中编写ren->kill,并且肯定会多次调用它。因此覆盖了最后一次的价值。而您可能打算将 ren[0] 用于 rist 时间,将 ren[1] 用于第二次等等。如果您进行调试,您就会知道。
    猜你喜欢
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多