2

我想知道您是否可以帮助我解决我不太了解的 C 字符串问题。我有一个向其发送 3 个字符指针的函数。在这个函数中,char 指针被正确地移动和修改。但是,当我返回调用它们的主函数时,所述函数并没有改变。我按值传递是错误的吗?这是我的代码示例:

int main(void) 
{ 
    LPSTR path = (char*)malloc(strlen(START_PATH));

    strcpy( path, START_PATH );

    char* newstr = (char*)malloc(PATH_SIZE);

    TrimVal(path, "*.*", newstr);

    //Do Stuff

    return 0;
}

void TrimVal(char* modify, char* string, char* newstr)
{ 
      newstr[0] = '\0';

      modify = strncat(newstr, modify, (strlen(modify) - strlen(string)));

      return;
}      

注意:假设PATH_SIZE是一个大小值,并且START_PATH是一个字符数组

4

7 回答 7

6

在这样做

 modify = strncat(newstr, modify, (strlen(modify) - strlen(string)));

您正在修改指针,而不是指针指向的内容。

当您传递path给 TrimVal 时。它将传入path例如0x12345的内存位置

当你这样做时modify =,将局部变量更改modify为新的内存位置,例如 0x54321

当你回到 main 时,它只有一个指向 0x12345 的指针,当它在那里看时,什么都没有改变。

您可以通过以下方式轻松解决您的问题

{ 
...
TrimVal(&path, "*.*", newstr);
... 
}

void TrimVal(char** modify, char* string, char* newstr)
{ 

      newstr[0] = '\0';

      *modify = strncat(newstr, *modify, (strlen(*modify) - strlen(string)));

      return;

}    
于 2009-10-15T15:24:26.007 回答
1
void TrimVal(char* modify, char* string, char* newstr)

在函数内部更改 、 或 的值modifystring调用函数的变量没有影响。newstrTrimVal()

改变、或函数内部的内容将反映在调用函数的变量上。modifystringnewstrTrimVal()

所以

void TrimVal(char* modify, char* string, char* newstr)
{
    newstr[0] = '\0'; /* will be reflected in the calling function */
    modify = "a new string"; /* won't be reflected */
}

我认为您的功能只需清除一些代码即可完成您想要的操作。

哦......并且您的path变量存在内存泄漏:您为它分配了一些空间,然后通过为变量分配不同的值立即丢失该空间的地址path

于 2009-10-15T15:30:22.687 回答
1

除了这个线程中提出的许多其他好点之外,还有几点:

    LPSTR path = (char*)malloc(strlen(START_PATH));

如果这是 C,则不应强制转换 的返回值malloc。(见C 常见问题 7.7b

更重要的是,它的计算strlen中不包括终止\0。因此,内存path指向的内存量比要保存的所需内存量少一个字符START_PATH加上\0. 所以:

    strcpy(path, START_PATH);

通过将 1 写入 指向的内存来调用未定义的行为path

于 2009-10-15T18:21:02.877 回答
0

关于您对 malloc 调用的返回类型进行转换的风格只有一条评论。投射时,这可以隐藏错误。

这将是一种更好的风格。

包括 stdlib.h 并尝试将 malloc 调用作为类型无关。

char *ptr_char = NULL;

ptr_char = malloc(sizeof(*ptr_char));

希望这可以帮助,

于 2009-10-16T04:59:37.020 回答
0

我看到前两个陈述有问题。您将 path 声明为指针 char 并为其分配存储在此地址持有者中的内存。在您的下一条语句中,您将更改 path 中的值,将其指向 char 数组的开头 START_PATH。您分配的内存现在丢失了。

此外, strncat 不会调用 malloc 进行连接。预计您传递的缓冲区足够大以容纳 concat,这是潜在的安全风险(缓冲区溢出)。

于 2009-10-15T15:44:08.510 回答
0

如果你希望你的 char* 变量在函数中被修改并且你想通过引用传递,你需要将它作为 char* 传递。请记住,您是通过引用传递指针,因此需要额外的间接层(传递 char确实通过引用传递某些东西 - 单个字符!)

于 2009-10-15T15:26:00.810 回答
0

C 并没有真正的传递引用。您在这里所做的是按值传递指针。C 中的字符串由指向char的指针表示。因此,在函数TrimVal中,您可以修改字符串的内容(即指向的数据),但不能修改指针本身。

strncat修改第一个参数的内容并返回相同的值。

如果要更改TrimVal内的路径值,则应将指针传递给指针,如下所示:

...

TrimVal(path, "*.*", newstr);

...

void TrimVal(char** modify, char* string, char* newstr)

{ 
  newstr[0] = '\0';
  *modify = strncat(newstr, *modify, (strlen(*modify) - strlen(string)));
  return;
} 
于 2009-10-15T15:27:59.140 回答