我正在研究一个需要我创建唯一字符串的类项目,并且我希望将数字连接到字符串。但是我无法访问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标准库)?
答案 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()
它。
如果您选择这样做,可能是一个更好的选择
memset()
。有一点要记住,这样,每次调用函数都会清理之前的结果。
编辑:
如果您无法使用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);
}