对C来说还是新手,但我想我最近分配和管理内存,直到最近遇到这个问题。
我正在开发一个“make”工具。 (这不是家庭作业,只是我朋友的旧任务,我认为我可以从中收集宝贵的实践。)我相信你们大多数人都知道,makefile有各种各样的目标,而这些目标在目标命令之前必须遵守这些目标。可以执行。
为了存储解析makefile时找到的给定目标依赖项的数据,我做了以下内容:
typedef struct{
char* target;
char** dependency_list;
}dependency_tracker;
为了跟踪多个dependency_trackers,我声明(并随后分配)以下变量。 (注意“total_number_of_targets”之后的“+4”。程序没有用,我的问题是为什么。)
dependency_tracker** d_tracker_ptr = (dependency_tracker**) malloc((total_number_of_targets+4)*sizeof(dependency_tracker*));
然后我使用以下行将指针发送到解析方法:
parse_file(filename,&d_tracker_ptr);
在parse_file函数中,我相信这些是我做的最重要的调用(省略字符串解析调用)。请注意,target_counter是到目前为止解析的目标数。我认为其他一切都应该可以解决:
dependency_tracker** tracker_ptr = *tracker_ptr_address; // tracker_ptr_address is the pointer I passed to the function above
// declare and allocate for the new struct we are creating
dependency_tracker* new_tracker_ptr = (dependency_tracker*) malloc(sizeof(dependency_tracker));
char* new_tracker_ptr_target = (char*) malloc((size_of_target)*sizeof(char)); // size_of_target is the string length
new_tracker_ptr->target = new_tracker_ptr_target;
*(tracker_ptr+target_counter*sizeof(dependency_tracker*)) = new_tracker_ptr;
正如我之前提到的,我必须分配四个空间(dependency_tracker *),而不是我想要的,以便在没有段错误的情况下完成该程序。
我得出的结论是,这是因为我覆盖了我为传递给parse_file的指针分配的空间。
我的问题是:为什么会这样?即使需要空指针,也不需要4个附加指针的空间。如果我在原始调用malloc
中分配少于25个额外字节的内容,程序会产生段错误如果有任何需要澄清,请告诉我。我知道这是一部小说。
答案 0 :(得分:3)
这是破碎的:
*(tracker_ptr+target_counter*sizeof(dependency_tracker*)) = new_tracker_ptr;
指针大小由C计算。你想要:
tracker_ptr[target_counter] = new_tracker_ptr;
正如我在评论中提到的那样,你不允许在字符串中使用空终结符。
另一条评论:C不需要malloc
上的演员,而使用一个会引发麻烦。另外,您只需取消引用您指定的指针即sizeof
,这样更安全。所以只说:
dependency_tracker *new_tracker_ptr = malloc(sizeof *new_tracker_ptr);
char* new_tracker_ptr_target = malloc(size_of_target * sizeof *new_tracker_ptr_target);
dependency_tracker *new_tracker_ptr = malloc(*new_tracker_ptr);
new_tracker_ptr->target = new_tracker_ptr_target;
此外,您可能需要重新考虑变量名中的空洞单词。我实际上是冗长的解释性标识符的忠实粉丝,但是"跟踪器"和"目标"是如此模糊,以至于它们几乎没有增加清晰度同样,在变量名称中嵌入类型信息a la _ptr
在30年前是一种时尚。现在结束了。如果您有一个功能,声明和变量名称不能在同一屏幕上显示,则功能太大。
答案 1 :(得分:1)
*(tracker_ptr+target_counter*sizeof(dependency_tracker*)) = ...
这就是问题所在。 Pointer arithmetic不能那样运作。使用正确类型(即非sizeof(anyhing)
)指针算法时,您不必乘以char*
。更好的是,您根本不必使用指针算法。
tracker_ptr[target_counter] = ...
就是所需要的。