【问题标题】:C++ pass by reference WCHAR** into a functionC++ 通过引用 WCHAR** 传递给函数
【发布时间】:2017-08-12 12:52:53
【问题描述】:

我编写了以下代码,其中我将 WCHAR** 引用传递给函数,以便将其归档到函数中。在函数内部,我正在填充这个二维数组。我正在尝试通过引用传递来完成这项工作。

BOOL get_file_names(WCHAR** outname)
{

    WCHAR **outhandlername = NULL;


    if (get_all_the_file_handelers( &outhandlername) > 0)
    {

        (*outname)[0] = *outhandlername[0];

    }

    return ret;
}

int get_all_the_file_handelers(WCHAR** outhandleName )
{



    for (i = 0; i < 10; i++)
    {
     WCHAR *handleName = get_handle_name(handle, i);

    outhandleName = (WCHAR**)realloc(outhandleName, sizeof(WCHAR)*(10 + 1));
    (*outhandleName) = (WCHAR*)realloc(*outhandleName, sizeof(WCHAR)*(1024));
    *outhandleName = handleName;

    }
    return 0;

}

但这似乎不起作用,任何人都可以帮助我了解在这种情况下,WCHAR 数组的引用传递是如何工作的。当我有WHCAR** 时,将&amp;WCHAR 传递给第二个函数是正确的,在第二个函数中我应该如何为二维WCHAR 数组分配值


int _tmain(int argc, _TCHAR* argv[])
{
      WCHAR *outhandlename=NULL;
      get_file_names(&outhandlename);
      DBGLOG("handler name  %ls", outhandlename);

      return 0;
}

BOOL process_search_file_handle( WCHAR** str)
{
      *str = (WCHAR*) malloc(1024);
      *str = L"TestName";   
      return true;
}

BOOL get_file_names(WCHAR** outname)
    {

        WCHAR **outhandlername = NULL;


        if (get_all_the_file_handelers( &outhandlername) > 0)
        {

            *outname = outhandlername[0];
            DBGLOG("outhandlername value  %ls", outhandlername[0]);
            DBGLOG("str value  %ls", *outname);

        }

        return true;
    }

【问题讨论】:

  • 1) 没有二维数组。 2) 有什么理由不使用 C++ 功能?
  • 其实没理由,我是c++新手,这恰好是我的第一个项目,虽然这是可能的,这就是我选择它的原因。我可以在这里采取什么其他方法
  • 您不是通过引用传递,而是通过值传递...&amp; 运算符是地址运算符。如果您在对get_all_the_file_handelers 的函数调用中将其删除,代码可能会执行您的预期,但是,我不确定函数内部分配的内存如何知道如何释放自己。
  • ` outhandleName = (WCHAR**)realloc(outhandleName, sizeof(WCHAR)*(10 + 1));` 分配 22 个字节,然后转换为指针类型。指针的大小与WCHARs 不同。也许你的意思是sizeof(WCHAR*)。接下来,(*outhandleName) = (WCHAR*)realloc(*outhandleName, sizeof(WCHAR)*(1024)); 尝试重新分配 *outhandleName 指向的内容……但从来没有第一次分配,所以这很奇怪。但即使成功了,*outhandleName = handleName; 也会用来自handleName 的值覆盖指针,从而泄漏之前的分配。
  • 当一个人进入指向指针的指针时......事情就会变得烦人。如果您是 C++ 新手,那么在该级别工作会过于复杂。尝试使用可以轻松调整大小的容器并自行处理细节,例如std::vector

标签: c++ pointers pass-by-reference wchar


【解决方案1】:

将 outHandleName 设置为 realloc 的输出后,您已经覆盖了 outHandleName,因此您将无法从调用函数更改 outHandleName 的值。

你可以说:

*outHandleName = (WCHAR**) realloc(...);

您还必须将get_all_the_file_handelers 的方法标头更改为:

int get_all_the_file_handelers(WCHAR *** outHandleName)

这是因为您在此方法中使用了指向双指针的指针。

此外,您不是通过引用传递 - 您是通过指针传递。

此外,您不应该在这里使用 realloc,因为您正在为数组进行初始分配。应在循环之前分配 10 个元素的数组,如下所示:

*outHandleName = (WCHAR **)malloc(sizeof(WCHAR *)*(10+1));
(*outHandleName)[10] = NULL;

请注意,空赋值 - 您正在为 10 个项目的数组中的 11 个项目分配空间,所以我假设您使用最后一个项目作为占位符 - 作为 NULL - 来标记数组的结尾。

最后,您不需要为 10 个句柄中的每一个都分配一个字符串缓冲区空间,因为您从 get_handle_name 中获取了一个字符串。

作为奖励,您没有返回任何内容,即使您的其余代码表明您是。

最后的方法是:

int get_all_the_file_handelers(WCHAR ***outHandleName) {
  *outHandleName = (WCHAR **)malloc(sizeof(WCHAR *)*11);
  (*outHandleName)[10] = NULL;
  for(int i = 0; i < 10; i++) {
    WCHAR *handleName = get_handle_name(handle, i);
    (*outHandleName)[i] = handleName;
  }
  return .... /* WHAT AM I RETURNING?? */ ;
}

【讨论】:

  • 当您使用 wcscpy_s 时,您正在将字符串从一个位置复制到另一个位置。您不能使用赋值运算符来复制字符串。如果您使用变量wchar *a 并说*a = L"Test Name",那么您实际上是在尝试将字符串的地址填充到a 指向的内存区域中。您真正想要做的是将 a 的值替换为指向您的字符串文字的指针,或者您想要预分配一个缓冲区 (a = (wchar *)malloc(sizeof(wchar) * size_of_buffer)),然后使用 wcscpy_s 复制您的字符串。
  • 这很难解释,但基本上不可能通过单个赋值来复制字符串。您可以使用循环,但最好使用已经为复制字符串而编写的方法。另一方面,如果您只想将 wchar * 变量的值设置为 wchar * 字符串文字,请使用不带星号的赋值。您不是在尝试修改“variablename”指向的内存区域,而是在尝试更改“variablename”指向的内容;您正在尝试使“variablename”指向您的字符串“Test Name”。
  • 嗯....这可能是因为您尝试使用“%s”打印 WCHAR 字符串 - 尝试“%ls”。
  • 您是将outhandlername 作为&amp;outhandlername 还是outhandlername 传递给此函数?如果是前者,请将您的分配更改为*str = (*outhandlername)[0]
  • 那时,我不确定还有什么建议。仔细检查您的函数 get_handle_name 是否返回正确的值。尝试直接打印该函数调用的值,然后在代码中与您的结果进行比较。这将帮助您确定您在此处发布的代码是否存在问题,或者问题是否来自代码的其他部分。
【解决方案2】:

这是一些使用标准库生成宽字符串列表的示例代码。您应该稍后学习如何处理指针数组,但我建议您先学习如何使用 STL。

#include <cstdlib>
#include <experimental/filesystem>
#include <iostream>
#include <locale>
#include <string>
#include <vector>

#if _WIN32 || _WIN64
// Windows needs a little non-standard magic for this to work.
#include <io.h>
#include <fcntl.h>
#include <locale.h>
#endif

using std::endl;
using std::size_t;
using std::wcout;
using std::experimental::filesystem::path;

void init_locale(void)
// Does magic so that wcout can work.
{
#if _WIN32 || _WIN64
  // Windows needs a little non-standard magic.
  constexpr char cp_utf16le[] = ".1200";
  setlocale( LC_ALL, cp_utf16le );
  _setmode( _fileno(stdout), _O_U16TEXT );
#else
  // The correct locale name may vary by OS, e.g., "en_US.utf8".
  constexpr char locale_name[] = "";
  std::locale::global(std::locale(locale_name));
  std::wcout.imbue(std::locale());
#endif
}

std::vector<std::wstring> files_in_wd()
// Returns a list of filenames in the current working directory.
{
  const path cwd = std::experimental::filesystem::current_path();
  std::vector<std::wstring> filenames;

  for ( const path& file : cwd )
    filenames.emplace_back( file.filename().wstring() );

  return filenames;
}

int main(void)
{
  init_locale();

  const std::vector<std::wstring> filenames = files_in_wd();

  for ( const std::wstring& ws : filenames )
    wcout << ws << endl;

  return EXIT_SUCCESS;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-07
    • 2021-11-04
    • 2014-12-03
    • 2023-03-08
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多