gpt4 book ai didi

c - malloc 后大小为 8 的无效写入

转载 作者:行者123 更新时间:2023-11-30 18:54:52 26 4
gpt4 key购买 nike

我目前正在为我的学校开发一个项目,但我的代码遇到了问题。该程序的目的是实现一个插件管理器,在目录中搜索所有“*_plugin.so”文件,并将插件描述符添加到一个简单的链表中。

C 代码:

      //struct of a single node
typedef
struct _chainon_ {
plugin_descriptor * desc;
struct _chainon_ * next;
} Chainon;

// manager that contains sentry node & number of plugins contained by the list
struct plugin_manager_t {
int nbElts;
Chainon * sentinel;
};

typedef
struct {
const char * m_name; // nom du filtre
const char * m_description; // description de l'effet du filtre
filter_function m_filtre; // fonction de réalisation du filtre
} plugin_descriptor;

现在是register_plugin函数,当程序在目录中找到一个新插件时,它会被调用,它会调用一个init_函数来调用register_plugin:

  void
init_(plugin_manager * pm)
{
register_plugin(pm,
"null_filter",
"Exemple de filtre inutile",
null_filter);
}

然后应该将新插头添加到列表中:

  void
register_plugin(plugin_manager * pm,
const char filter_name[],
const char filter_description[],
filter_function the_filter)
{
Chainon * n = (Chainon *)malloc(sizeof(Chainon)); //new node that i want to add to the linked list
n->desc = NULL;
n->next = NULL;
n->desc->m_name = filter_name;
n->desc->m_description = filter_description;
n->desc->m_filtre = the_filter;
Chainon * current = pm->sentinel;
for(int i=0;i<pm->nbElts;i++){
current=current->next;
i++;
}
current->next = n;
}

这就是我在执行该程序时使用 valgrind 得到的结果:

> ==7022== Invalid write of size 8
> ==7022== at 0x4015A7: register_plugin (pluginmanager.cc:165)
> ==7022== by 0x66E1BDC: init_ (null_filter_plugin.cc:23)
> ==7022== by 0x401483: discover_plugins (pluginmanager.cc:113)
> ==7022== by 0x401187: main (main.cc:17)
> ==7022== Address 0x0 is not stack'd, malloc'd or (recently) free'd
> ==7022==
> ==7022==
> ==7022== Process terminating with default action of signal 11 (SIGSEGV)
> ==7022== Access not within mapped region at address 0x0
> ==7022== at 0x4015A7: register_plugin (pluginmanager.cc:165)
> ==7022== by 0x66E1BDC: init_ (null_filter_plugin.cc:23)
> ==7022== by 0x401483: discover_plugins (pluginmanager.cc:113)
> ==7022== by 0x401187: main (main.cc:17)
> ==7022== If you believe this happened as a result of a stack
> ==7022== overflow in your program's main thread (unlikely but
> ==7022== possible), you can try to increase the size of the
> ==7022== main thread stack using the --main-stacksize= flag.
> ==7022== The main thread stack size used in this run was 8388608.

我是 C 编程新手

但我不明白为什么我无法初始化“n->desc->name”,因为我使用 malloc 分配了内存,然后将所有内容初始化为 NULL ?

任何帮助将不胜感激!

谢谢

最佳答案

您的代码有几个问题,其中一些是小问题,另一些则导致发布的 valgrind 输出,

  1. 这并不是真正的问题,只是你don't need to cast the return value of malloc()

    Chainon *n = malloc(sizeof(Chainon));

    没关系,不需要 Actor 。

  2. 你需要检查malloc()是否成功,而不仅仅是假设它成功了,在正常情况下它不会失败,但如果失败你的程序不会处理它,如果它有一些敏感数据需要存储在硬盘中或任何其他需要干净退出的情况,你会给程序用户带来很多问题,所以你应该确保你的程序干净退出,因此,检查 malloc() 的返回值是一件非常好的事情,只需在每次调用 malloc() 后立即检查 NULL 即可并根据故障发生的情况进行处理。

  3. 您不为结构成员分配空间,每个指针在取消引用之前都必须指向有效内存,因此您必须确保它确实指向有效内存,无法检查未初始化的指针,因此在某些情况下如果您要在可能的检查后初始化指针,请将其初始化为 NULL

    在一种情况下您会这样做,但随后您取消引用 NULL 指针,这是未定义的行为。

使用上面的所有建议,您的函数必须像这样重写*

void
register_plugin(plugin_manager * pm,
const char *const filter_name,
const char *const filter_description,
filter_function the_filter)
{
Chainon *chainon;
plugin_descriptor *descriptor;
Chainon *current
int i;
if (pm == NULL)
return;
chainon = malloc(sizeof(*chainon));
if (chainon == NULL)
return;
chainon->next = NULL;

descriptor = malloc(sizeof(*descriptor));
if (descriptor == NULL)
{
free(chainon);
return;
}
chainon->desc = descriptor;

descriptor->m_name = filter_name;
descriptor->m_description = filter_description;
descripotor->m_filtre = the_filter;

current = pm->sentinel;
if (current == NULL)
return;
for(i = 0 ; ((i < pm->nbElts) && (current->next != NULL)) ; ++i)
current = current->next;
current->next = chainon;
}

*我更改的一些内容并不是真正必要的。我只是认为这样更好。

关于c - malloc 后大小为 8 的无效写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29350073/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com