在C中清除char数组,没有任何标准库

时间:2015-11-19 14:36:13

标签: c arrays function pointers

我正在研究一个需要我创建唯一字符串的类项目,并且我希望将数字连接到字符串。但是我无法访问C标准库(memset,malloc等)。我做了这个有效:

WNetCancelConnection2

但是当我用多个字符串测试它时,我意识到newName正在被反复使用。对于前者 此测试文件输出以下内容:

char* concat(char* name, int num) {
  int i, j;
  char newName[50], stack[5];

  for(i=0; name[i]!='\0'; ++i) {
    newName[i] = name[i];
  }

  for (j=0; num>=1 || num==0; j++) {
    stack[j] = (num % 10) + '0';
    num = num / 10;
    if (num==0) break;
  }

  while (j>=0) {
    newName[i++] = stack[j--];
  }
  name[0] = '\0';

  return newName;
}

它成功地将1添加到rebecca,但是当我在bill上调用concat时,它会覆盖前5个字母但在newName中保留相同的字符。 问题:如何清除char数组,以便下次调用它时将其设置为空,或动态分配它(不使用C标准库)?

3 个答案:

答案 0 :(得分:1)

不使用malloc,您可以简单地将内存放在调用函数的堆栈上,以保留在需要它的范围内。将缓冲区指针添加到参数列表更容易,如下所示:

char* concat(char *newName, char* name, int num) {
  int i, j;
  char stack[5];
   :
   :
}

int main() {
  char rebecca[50];
  char bill[50];

  concat(rebecca, "rebecca", 1);
  concat(bill, "bill", 2);

  write(rebecca);
  write(bill);
}

一般来说,分配将要使用的内存。嵌入式编程(可能需要运行几个月而不需要重新启动)可以避免像瘟疫这样的malloc,因为存在内存泄漏的风险。然后,您需要分配额外的空间,因为您可能在编译时不知道大小,然后理想地检查运行超过缓冲区的末尾。在这里,我们知道字符串大小和50个字符绰绰有余。

编辑: 另一个问题是你没有终止null。打印将一直持续到达到0x00。你的行

name[0] = '\0';

应该是

newName[i] = '\0';

答案 1 :(得分:0)

你有一个你忽视的重大问题。在您的函数中,newName是一个局部变量(数组),您将从函数返回它。这会调用undefined behavior。 UB的美妙之处在于,有时它出现按预期工作。

如果要从concat()函数返回,则需要采用指针并动态分配内存。此外,在main()中,在使用它之后,您需要free()它。

如果您选择这样做,可能是一个更好的选择

  1. 在调用者中定义数组。
  2. 将数组传递给函数。
  3. 在执行任何其他操作之前,在函数内部memset()
  4. 有一点要记住,这样,每次调用函数都会清理之前的结果。

    编辑:

    如果您无法使用memset(),则可以使用for循环

    for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
        arr[i] = 0;
    

    在下次传递数据之前清除数组。

答案 2 :(得分:0)

您将返回本地变量的地址。由于变量在函数返回时超出范围,因此会调用undefined behavior

您的函数应该为连接的结果动态分配内存,然后返回该缓冲区。您需要确保稍后free缓冲区以防止内存泄漏:

char* concat(char* name, int num) {
  int i, j;
  char *newName, stack[5];
  // allocate enough space for the existing string and digits for a 64-bit number
  newName = malloc(strlen(name) + 30);

  for(i=0; name[i]!='\0'; ++i) {
    newName[i] = name[i];
  }

  for (j=0; num>=1 || num==0; j++) {
    stack[j] = (num % 10) + '0';
    num = num / 10;
    if (num==0) break;
  }

  while (j>=0) {
    newName[i++] = stack[j--];
  }
  newName[i] = '\0';

  return newName;
}

int main() {

  char* rebecca = concat("rebecca", 1);
  char* bill = concat("bill", 2);

  Write(rebecca);
  Write(bill);

  free(rebecca);
  free(bill);
}