我有以下代码在过去几个月一直在运行,但最近有时会崩溃(在多线程应用程序中运行时):
struct some_struct {
char* m_str1;
char* m_str2;
}
struct some_struct*
set_some_struct(const char* p_str1, const char* p_str2) {
struct some_struct* some_struct_ptr =
(struct some_struct*)malloc(sizeof(struct some_struct));
if (some_struct_ptr == NULL)
printf("malloc failed!\n");
size_t str1_len = strlen(p_str1) + 1;
size_t str2_len = strlen(p_str2) + 1;
some_struct_ptr->m_str1 = malloc(str1_len);
if (some_struct_ptr->m_str1 == NULL)
printf("malloc failed!\n");
some_struct_ptr->m_str2 = malloc(str2_len); // Crashes here
if (some_struct_ptr->m_str2 == NULL)
printf("malloc failed!\n");
strcpy(some_struct_ptr->m_str1, p_str1);
strcpy(some_struct_ptr->m_str2, p_str2);
return some_struct_ptr;
}
运行它给我“”0x7c81bb52处的指令“引用”0x00000002“处的内存。内存无法”读取“。”
上述代码是否存在明显错误,在某些情况下可能会出现错误行为?如果我在测试程序中单独运行该函数它可以正常工作,但它在整个应用程序中运行时总是崩溃。导致第三个malloc的一切似乎都很好。
编辑:进一步的调查让我相信,早先打电话给malloc
会搞砸这个。这样的事情甚至可能吗?如果我取消注释在set_some_struct
之前进行的函数调用,并且涉及多个mallocs
,那么set_some_struct
将运行正常。
答案 0 :(得分:2)
好吧,分配失败时所做的就是打印错误;也许打印掉了或你错过了?如果有多个线程运行此命令,输出可能会令人困惑。
其次,您没有检查输入指针。由于崩溃是一个读取,并且所有其他通过指针的访问都是写入新分配的区域,我怀疑一个或多个参数是NULL
指针。你应该检查一下。
此外,您不应该在C(see here for reasons)中转换
的返回值,如果您不包含malloc()
malloc()
,则可能隐藏错误。
如果字符串是常量,只需调用一次stdlib.h
就可以节省内存和速度,首先将三个分配的大小相加,然后相应地设置指针。
答案 1 :(得分:1)
if (some_struct_ptr == NULL)
printf("malloc failed!\n");
从这一点开始,你正在使用垃圾指针。以下代码会出现同样的问题。
if (some_struct_ptr->m_str1 == NULL)
printf("malloc failed!\n");
if (some_struct_ptr->m_str2 == NULL)
printf("malloc failed!\n");