【问题标题】:C Variable changes after initializing other variablesC变量在初始化其他变量后发生变化
【发布时间】:2014-11-13 19:48:22
【问题描述】:

我正在用 C 语言编写一个命令行待办事项列表程序,并且出现了一些奇怪的行为。 Todos 存储在包含int 优先级和char[128] 名称的结构中。它们是使用接收这些参数并返回具有这些值的已分配和初始化结构的函数创建的。

返回的结构体最初是正确的,但是在再初始化 8 个结构体变量后,第一个初始化的结构体的值开始发生变化。我的猜测是,由于分配的内存不足,以前的值被新的值覆盖。我通过将馈送到malloc() 的大小从sizeof(TaskP) 增加到sizeof(int) + sizeof(char[128]) 暂时解决了这个问题。但是,我确信有更好的方法,并且非常感谢您解释为什么 malloc(sizeof(TaskP) 没有分配足够的内存(如果是这样的话)和正确的约定。

这是我的代码:

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

struct Task {
    char description[128];              /* description of the task */
    int priority;                       /* task priority */
};

typedef  struct Task* Task;


Task createTask (int priority, char *desc)
{
  Task newTask = malloc(sizeof(Task));
  if (newTask) {
    newTask->priority = priority;
    strcpy(newTask->description, desc);
  }
  return newTask;
}

int main(int argc, const char * argv[])
{
    Task taskList[10];

    Task task1 = createTask(9, "task 1");
    printf("task1: %d\n", task1->priority);  /* I put printfs */
    Task task2 = createTask(3, "task 2");
    printf("task1: %d\n", task1->priority);  /* after every call */
    Task task3 = createTask(2, "task 3");
    printf("task1: %d\n", task1->priority);  /* to createTask() */
    Task task4 = createTask(4, "task 4");
    printf("task1: %d\n", task1->priority);  /* to watch the value */
    Task task5 = createTask(5, "task 5");
    printf("task1: %d\n", task1->priority);  /* of task1 change */
    Task task6 = createTask(7, "task 6");
    printf("task1: %d\n", task1->priority);
    Task task7 = createTask(8, "task 7");
    printf("task1: %d\n", task1->priority);
    Task task8 = createTask(6, "task 8");
    printf("task1: %d\n", task1->priority);
    Task task9 = createTask(1, "task 9");
    printf("task1: %d\n", task1->priority);
    Task task10 = createTask(0, "task 10");
    printf("task1: %d\n", task1->priority);

    return 0;
}

这是我的输出:

task1: 9
task1: 9
task1: 9
task1: 9
task1: 9
task1: 9
task1: 9
task1: 0
task1: 1802723700
task1: 1802723700

更新

我在发布到堆栈溢出后几秒钟就发现了问题。多么尴尬。问题是我只为大小为 8 字节的指针 (Task) 分配了足够的内存,而不是为大小为 132 字节的struct Task 分配了内存。感谢所有耐心回答的人,很抱歉浪费了您的时间。

【问题讨论】:

  • 请注意,typedef struct Task* Task; 令人困惑,尤其是当您有 struct Task 时。请不要typedef指针。
  • 我通常不会,但这是我的计算机科学教授预先编写的代码,我无法更改。不过谢谢。

标签: c struct malloc sizeof


【解决方案1】:

这就是问题所在。

Task newTask = malloc(sizeof(Task));

您分配了足够的内存来只保存一个指针,而不是struct Task

改成:

Task newTask = malloc(sizeof(*newTask));

FWIW,将Task 作为typedef 用于struct Task* 并不是一个好主意。使用起来会更好:

typedef struct Task Task;
typedef struct Task* TaskPtr;

然后使用

Task* newTaskPtr = malloc(sizeof(Task));

TaskPtr newTaskPtr = malloc(sizeof(Task));

【讨论】:

  • 我对此困惑了三天,将它展示给我的教授和几个研究生,他们都不知道出了什么问题,而我在发布后几秒钟就想出了同样的解决方案.多么尴尬。谢谢先生。
  • @rfarry,不客气。没有必要感到尴尬。我们大多数人都犯过类似的错误。
  • 经验丰富的 C 程序员遵守规则是有原因的通常不想隐藏。
  • 很遗憾教授们没有立即发现错误。您分配返回值malloc() 的变量的类型总是不同于您获得大小的类型(它是指向该类型的指针)。
猜你喜欢
  • 2016-03-11
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-02
  • 1970-01-01
  • 1970-01-01
  • 2010-10-31
相关资源
最近更新 更多