0

char *charheap;我在堆中创建一个长度为 32 字节的数组 ( ),并将所有元素初始化为\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应该返回一个指向连续块开头的指针,但我不知道如何正确实现它。有人可以给我一个提示或线索吗?

4

1 回答 1

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()将返回大小为0. 您想遍历整个charheap,因此只需使用该数组的大小(32在本例中)。

  int len = 32; /* or sizeof(charheap) if it is declared as an array */

以上两个修复应该足以让您的程序按预期运行(参见演示)。

但是,您不会检查以确保堆中有足够的空间来接受分配检查。charheap如果可用内存的开头和结尾之间的距离小于或等于所需大小,则分配应该失败。len您可以通过将 设置为您愿意在知道空间不足之前检查的最后一点来轻松地执行此操作。

  int len = 32 - s;

最后,当您尝试分配第三个字符串时,您的循环将跳过第一个分配的字符串,但会覆盖第二个分配的字符串。您的循环逻辑需要更改以跳过每个分配的字符串。您首先检查您的当前位置charheap是否免费。如果不是,则将您的位置提高字符串的长度,再加一个以跳过字符串的 '\0' 终止符。如果当前位置是免费的,则返回它。如果您无法找到免费位置,则返回NULL

char *char_alloc(int s) {
  int i = 0;
  int len = 32 - s;
  while (i < len) {
    if (charheap[i] == '\0') return &charheap[i];
    i += strlen(charheap+i) + 1;
  }
  return NULL;
}
于 2013-07-24T05:59:11.907 回答