gpt4 book ai didi

C - 字符串被函数无意中更改

转载 作者:行者123 更新时间:2023-11-30 19:15:24 24 4
gpt4 key购买 nike

我最近一直在使用一些 C 语言,现在我还比较新。我的主要问题是我传递给函数的字符串无意中更改为一组新的随机字符。我很难解释我的问题,因为我有一堆代码并且无法全部共享。但问题出在以下几个方面:

主函数中的这段代码:

char* name = "@";
Var v = NewVar(name, 0);
printf("%s\n", name);

打印:

Creating New Value w/ Name: @ 
@

——这是它应该打印的内容。但是,这段代码(在另一个函数中):

printf("Before: %s\n", split[counter]);
Var v = NewVar(split[counter], 0);
printf("After: %s\n", split[counter]);

打印:

Before: hi
Creating New Value w/ Name: �
After:�P�

“split”(来自上面的代码)只是一个二维数组,定义如下:

char** split = str_split(path, '/')

“NewVar()”函数如下:

Var NewVar(char *name, int value){
printf("Creating New Value w/ Name: %s\n", name);
Var v;
v.value = value;
v.name = name;
v.varsLen = 0;
v.vars = (Var*)malloc(sizeof(struct Vars));
return v;
}

我之前多次注意到这个问题,但到目前为止我已经找到了解决方法。任何关于为什么会这样的建议或解释都会非常有帮助。

编辑:这是一个完整的工作示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char** strSplit(char* base, const char* delim){
char* result[0];
char *token;
char str[strlen(base)];
strcpy(str, base);
token = strtok(str, delim);
int counter = 0;
while( token != NULL ) {
result[counter] = token;
token = strtok(NULL, delim);
counter++;
}
char** split = malloc(counter * sizeof(char*));
for(int i = 0; i < counter; i++){
split[i] = malloc(sizeof(result[i])+1);
result[i][strlen(result[i])] = '\0';
split[i] = result[i];
}
split[counter] = 0;
return split;
}

typedef struct Vars{
char* name;
struct Vars* vars;
int value;
int varsLen;
} Var;

Var NewVar(char *name, int value){
printf("Creating New Value w/ Name: %s\n", name);
Var v;
v.value = value;
v.name = name;
v.varsLen = 0;
v.vars = (Var*)malloc(sizeof(struct Vars));
return v;
}

void test(char** split){
char* name = split[0];
Var v = NewVar(name,0);
printf("After: %s\n", name);
}

int main(int argc, char const *argv[])
{
char* name = "@";
Var v = NewVar(name, 0);
printf("%s\n", name);
char** split = strSplit("@/dir1/dir2", "/");
printf("Before: %s\n", split[0]);
test(split);
return 0;
}

打印:

Creating New Value w/ Name: @
@
Before: @
Creating New Value w/ Name: @
After:

最佳答案

让我们来剖析一下str_split() ,我们可以吗?

char** strSplit(char* base, const char* delim){
char* result[0];

我们的第一个错误。不能有零长度数组。另外,您稍后会使用该数组,因此即使您可以拥有零长度数组,您也无法对它们进行索引。

    char *token;
char str[strlen(base)];
strcpy(str, base);

下一个错误。 str太小,无法容纳 base ,自 strlen()不计算空终止符。

    token = strtok(str, delim); 
int counter = 0;
while( token != NULL ) {
result[counter] = token;

滥用 result .

        token = strtok(NULL, delim);
counter++;
}
char** split = malloc(counter * sizeof(char*));

记住这一点,split有足够的空间容纳counter char *是...

    for(int i = 0; i < counter; i++){
split[i] = malloc(sizeof(result[i])+1);

混淆了strlen()sizeof() .

        result[i][strlen(result[i])] = '\0';

没用。如果somestring[strlen(somestring)]还没有'\0' ,它不会是strlen(somestring) .

        split[i] = result[i];

这会泄漏分配给 split[i] 的内存并保留指向 str 的指针,当函数返回时超出范围。替换为 strcpy() .

    }
split[counter] = 0;

你还记得多少空间split有吗?

    return split;
}

关于C - 字符串被函数无意中更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32641284/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com