我在堆中创建一个长度为32个字节的数组(char *charheap;
),并将所有元素初始化为\0
。这是我的主要功能:
int main(void) {
char *str1 = alloc_and_print(5, "hello");
char *str2 = alloc_and_print(5, "brian");
}
char *alloc_and_print(int s, const char *cpy) {
char *ncb = char_alloc(s);// allocate the next contiguous block
if (ret == NULL) {
printf("Failed\n");
} else {
strcpy(ncb, cpy);
arr_print();// print the array
}
return ncb;
}
以下是我实施的内容:
/char_alloc(s): find the FIRST contiguous block of s+1 NULL ('\0')
characters in charheap that does not contain the NULL terminator
of some previously allocated string./
char *char_alloc(int s) {
int len = strlen(charheap);
for (int i = 0; i < len; i++) {
if (charheap[0] == '\0') {
char a = charheap[0];
return &a;
} else if (charheap[i] == '\0') {
char b = charheap[i+1];
return &b;
}
}
return NULL;
}
预期输出:(\
表示\0
)
hello\\\\\\\\\\\\\\\\\\\\\\\\\\\
hello\brian\\\\\\\\\\\\\\\\\\\\\
此解决方案完全错误,我打印出两个失败。 :(
实际上,char_alloc
应该返回指向连续块开头的指针,但我不知道如何正确实现它。有人能给我一个提示或线索吗?
答案 0 :(得分:3)
您的函数正在返回指向局部变量的指针,因此调用者会收到指向无效内存的指针。只需将指针返回到charheap
,这就是你想要的。
return &charheap[0]; /* was return &a; which is wrong */
return &charheap[i+1]; /* was return &b; which is wrong */
您的for
循环使用i < len
作为终止条件,但是,由于charheap
已填充\0
,strlen()
将返回{{1}的大小}}。您想迭代整个0
,所以只需使用该数组的大小(在这种情况下为charheap
)。
32
上述两个修复程序应该足以让您的程序按预期运行(请参阅demonstration)。
但是,您不进行检查以确保堆中有足够的空间来接受分配检查。如果可用内存的开头与 int len = 32; /* or sizeof(charheap) if it is declared as an array */
的结尾之间的距离小于或等于所需的大小,则您的分配将失败。您可以通过将charheap
设置为您愿意检查的最后一点,然后再知道没有足够的空间来轻松地执行此操作。
len
最后,当您尝试分配第三个字符串时,您的循环将跳过第一个分配的字符串,但会覆盖第二个分配的字符串。您的循环逻辑需要更改为跳过每个分配的字符串。您首先检查 int len = 32 - s;
中的当前位置是否空闲。如果不是,则按字符串的长度增加位置,再加上一个以跳过字符串的'\ 0'终止符。如果当前位置是免费的,则将其退回。如果您无法找到免费地点,请返回charheap
。
NULL