【问题标题】:Reassigning output pointer in function [duplicate]在函数中重新分配输出指针
【发布时间】:2019-04-30 02:10:45
【问题描述】:

我想知道为什么当我运行以下代码时,t 的值在调用 get 之后与之前相同。

我觉得问题在于第 11 行的重新分配,c = tmp - 但希望有人能指出我正确的方向吗?

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

BOOL get(COMPUTER_NAME_FORMAT f, WCHAR* c) {
    DWORD s = 0;
    WCHAR* tmp = NULL;
    GetComputerNameExW(f, tmp, &s);
    tmp = (WCHAR*)realloc(tmp, sizeof(WCHAR) * s);
    GetComputerNameExW(f, tmp, &s);
    c = tmp;
    return TRUE;
}

void _tmain(int argc, _TCHAR* argv[])
{

    WCHAR* t = TEXT("thisisatest");
    BOOL res = get(ComputerNameDnsHostname, t);
    printf("%Ls\n", t);
}

为简洁起见,上面的代码已经去掉了错误处理代码。另外,我怀疑两次调用 GetComputerNameExW() 之间存在竞争条件。

【问题讨论】:

  • 为函数的参数分配新值在该函数之外没有任何影响。 (如果你调用get(ComputerNameDnsHostname, 0),你期望会发生什么?0 的值会改变吗?)
  • 在单线程程序中不能有同步调用的竞争条件。
  • 仔细看realloc的签名。请注意它如何返回一个新指针。你有没有想过为什么需要它?
  • @George "名称的长度可能大于MAX_COMPUTERNAME_LENGTH 个字符,因为DNS 允许更长的名称。为确保此缓冲区足够大,请将此参数设置为NULL 和使用lpnSize 参数中返回的所需缓冲区大小。"
  • 第二个 GetComputerNameExW 函数和 realloc 用于异常处理?例如内存泄漏或不相信win api..我不明白

标签: c


【解决方案1】:

您只是在get(COMPUTER_NAME_FORMAT f, WCHAR* c) 函数中修改main 的t 指针的参数副本。

效果不会传播到get 之外。 您正在将 tmp 的值分配给在 get 返回后丢失的临时指针。

get 中将c 传递为WCHAR** c,如下所示:

BOOL get(COMPUTER_NAME_FORMAT f, WCHAR** c){
  //stuff
  tmp = (WCHAR*)realloc(tmp, sizeof(WCHAR) * s);
  *c=tmp;
  //other stuff
}

【讨论】:

  • 因此,当在 get 中将 WCHAR* t 作为 WCHAR* c 传入时,我只是将 t 的地址作为 c 传入,然后将所述地址替换为 WCHAR* tmp 的地址(其中,现在我想起来了,我知道......)所以使用指向指针的指针可以解决它,因为我只需替换一级指针指向的二级指针......我可以忍受那...
  • 正确,但t 本身从未被修改过。
猜你喜欢
  • 2019-06-12
  • 2019-10-19
  • 1970-01-01
  • 1970-01-01
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
  • 2018-08-24
  • 2017-04-17
相关资源
最近更新 更多