c - C应用程序中的内存分配

标签 c malloc calloc

我目前正在编写一个小应用程序来重新熟悉 C(自从我上次编写任何程序以来已经有一段时间了),并且像大多数人一样,我遇到了一个我无法解决的内存分配问题。

代码围绕不同面板、窗口和相关标题的设置。准确地说,这是我遇到问题的标题字符串的内存分配问题。

基础是一个结构,其中包含:

struct TFB_PANEL
{
    WINDOW *window;
    char *title;
};

这在头文件中的类型定义为:

typedef struct TFB_PANEL TfbPanel;

在相关的 C 文件中,我有以下方法来初始化固定大小的数组 TFB

int tfb_init()
{
    if (!_initialised) {
        return -1;
    }

    int i;
    for (i = 0; i < TYPE_MAX; i++) {
        TFB[i] = malloc(sizeof(TfbPanel*));
        TFB[i]->title = calloc((strlen(TYPES[i]) + 18), sizeof(char*));
        switch(i)
        {
            case A:
                sprintf(TFB[i]->title, " %s | r | h | s | t ", TYPES[i]);
                break;
            case B:
                sprintf(TFB[i]->title, " f | %s | h | s | t ", TYPES[i]);
                break;
            case C:
                sprintf(TFB[i]->title, " f | r | %s | s | t ", TYPES[i]);
                break;
            case D:
                sprintf(TFB[i]->title, " f | r | h | %s | t ", TYPES[i]);
                break;
            case E:
                sprintf(TFB[i]->title, " f | r | h | s | %s ", TYPES[i]);
                break;
        }

        TFB[i]->window = tfb_create_window(i);
    }
    return 0;
}

现在C初始化时出现错误。 A 和 B 的长度正确设置为 25 个字符。另一方面,C 在初始化后应该包含 24 个字符,但相反(从 tfb_create_window 中)我收到了

Program received signal EXC_BAD_ACCESS, Could not access memory
Reason: 13 at address 0x0000000000000000
0x00007fff930b9390 in strcmp()

检查堆栈显示 TFB[C] 已正确初始化,但标题元素未正确初始化。它包含一个 null 元素,就好像我从未调用过 calloc 一样。

请有人解释一下我哪里出了问题,或者为什么 A 和 B 正确初始化,但 C 杀死了应用程序。一切都很顺利,直到今天早上 6 点左右,从那以后就开始走下坡路了。

如果有帮助的话,可以通过调用 _create_window 和调用 tfb_get_title 来定义 tfb_create_window,如下所示:

char *tfb_get_title(int type)
{
    if (type >= TFB_MAX) {
        return (char*)NULL;
    }
    return TFB[type]->title;
}

WINDOW *tfb_create_window(int type)
{
    int height = ((LINES - WIN_OFFSET_Y) / 3);
    char *title = tfb_get_title(type);
    return _create_window(height, WIN_SIDEBAR_X, WIN_OFFSET_Y, 0, COLOUR_MAIN, title);
}

WINDOW *_create_window(int height, int width, int starty, int startx, int color, const char *title)
{
    WINDOW *window;
    window = newwin(height, width, starty, startx);
    box(window, 0, 0);
    mvwprintw(window, 0, 2, title);
    wbkgd(window, COLOR_PAIR(color));
    return window;
}

最佳答案

此代码中存在许多错误,最严重的是您使用 sizeof(Type*) 而不是 sizeof(Type)。后者是对象的实际大小,第一个只是指向该对象的指针的大小(在 64 位机器上为 8 个字节)。

这意味着 malloc(sizeof(TfbPanel*)) 为您的 TfbPanel 分配的内存太少,因此程序的其余部分具有未定义的行为。

calloc() 同样是错误的,但并不重要,因为您分配的内存是所需内存的八倍。

但是,calloc() 调用还有另一个错误:您将 18 添加到 strlen() 的结果中,这是您在sprintf() 调用。这太少了,因为 strlen() 的结果不包含空字节。

如果您可以使用 POSIX-2008 兼容的 libc(如 Linux 系统上的 glibc),则可以使用 asprintf() 而不是 sprintf(),它将自动为结果字符串分配足够的空间,避免任何可能的缓冲区大小错误。如果您无法使用该函数,请至少使用 snprintf() 以避免访问未分配的内存。

关于c - C应用程序中的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18800455/

相关文章:

C 程序制作一个计算器,可以执行简单的算术并在 int 和 double 变量之间切换

c - 如何知道一个c程序的堆栈溢出?

C -- 在没有 #include <stdio.h> 的情况下打印到屏幕?

c - 我的 fread 程序有什么问题?

c++将指针地址传递给函数

c - 在c中的套接字编程中读取或写入后没有代码运行

c - 动态存储器C

c - 与另一种有效的内存分配方法相比,为什么一种内存分配方法会失败?

c - C中malloc引起的内存泄漏

所有位 0 都可以是整数的陷阱表示吗?