返回c语言中的连续块

返回c语言中的连续块,c,heap,C,Heap,我在堆中创建一个长度为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);

我在堆中创建一个长度为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;
}
这个解决方案完全错误,我只打印了两个失败的:(


实际上,
char\u alloc
应该返回一个指向连续块开头的指针,但我不知道如何正确实现它。有人能给我一个提示或线索吗?

您的函数正在返回一个指向局部变量的指针,因此调用方收到一个指向无效内存的指针。只需将指针返回到
字符中即可eap
,这是您想要的

   return &charheap[0];   /* was return &a; which is wrong */

   return &charheap[i+1]; /* was return &b; which is wrong */
您的
for
循环使用
i
作为终止条件,但是,由于
charheap
\0
填充的,
strlen()
将返回
0
的大小。您希望迭代整个
charheap
,因此只需使用该数组的大小(
32

以上两个修复程序应该足以使您的程序按预期运行(请参阅)

但是,您没有进行检查以确保堆中有足够的空间来接受分配检查。如果可用内存的开始和
charheap
的结束之间的距离小于或等于所需的大小,则分配应该失败。您可以通过设置
len在你知道没有足够的空间之前,成为你愿意检查的最后一点

  int len = 32 - s;
最后,当您尝试分配第三个字符串时,您的循环将跳过第一个分配的字符串,但将覆盖第二个分配的字符串。您的循环逻辑需要更改以跳过每个分配的字符串。您首先检查
字符堆中的当前位置是否空闲。如果不是,则前进位置by字符串的长度,再加上一个以跳过字符串的“\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;
}
char*char\u alloc(int-s){
int i=0;
int len=32-s;
而(我
您的函数正在返回一个指向局部变量的指针,因此调用者会收到一个指向无效内存的指针。只需将指针返回到
字符堆中即可,这正是您所需要的

   return &charheap[0];   /* was return &a; which is wrong */

   return &charheap[i+1]; /* was return &b; which is wrong */
您的
for
循环使用
i
作为终止条件,但是,由于
charheap
\0
填充的,
strlen()
将返回
0
的大小。您希望迭代整个
charheap
,因此只需使用该数组的大小(
32

以上两个修复程序应该足以使您的程序按预期运行(请参阅)

但是,您没有进行检查以确保堆中有足够的空间来接受分配检查。如果可用内存的开始和
charheap
的结束之间的距离小于或等于所需的大小,则分配应该失败。您可以通过设置
len在你知道没有足够的空间之前,成为你愿意检查的最后一点

  int len = 32 - s;
最后,当您尝试分配第三个字符串时,您的循环将跳过第一个分配的字符串,但将覆盖第二个分配的字符串。您的循环逻辑需要更改以跳过每个分配的字符串。您首先检查
字符堆中的当前位置是否空闲。如果不是,则前进位置by字符串的长度,再加上一个以跳过字符串的“\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;
}
char*char\u alloc(int-s){
int i=0;
int len=32-s;
而(我
charheap[i]而不是charheap[0]?此处
strlen(charheap)
,您尚未创建或通过问题中所写的任何数组字符堆。您需要在循环检查中使用大小s。每当发现非零时,重新开始计数到s。for循环应该是到s,而不是len。在for循环中放置一个while循环,计数到len,如果结束则失败。如果需要,请重置i。@i已创建在heap(参见第一句):)charheap[i]而不是charheap[0]?在这里
strlen(charheap)
,您没有创建或传递任何数组charheap,因为您在问题中写道,您需要在循环检查中使用大小s。每当发现非零时,重新开始计数到s。for循环应该是到s,而不是len。在for周围放置一个while循环,以计数到len,如果到达末尾,则失败。如果需要,请重置i。@我在堆中创建的文件(请参阅第一句):)感谢您的回答。让我困惑的是“如何返回指向连续块开头的指针”,感谢您的帮助。除了当我尝试插入第三个字符串时,它工作得很好。它只是替换第二个字符串,而不是继续插入。你知道发生了什么吗?我想那个bug是你原来程序的一部分。实际上,您需要跳过以前分配的每个字符串。这意味着你的循环逻辑必须和你写的不同。你能给我一些提示吗?因为我真的很困惑如何“跳过之前分配的每个字符串”非常感谢你。谢谢你的回答。让我困惑的是“如何返回指向连续块开头的指针”,感谢您的帮助。除了当我尝试插入第三个字符串时,它工作得很好。它只是替换第二个字符串,而不是继续插入。你知道发生了什么吗?我想那只虫子是你的起源之一