通过指针或使用mem alloc的指针向函数发送字符串数组?

通过指针或使用mem alloc的指针向函数发送字符串数组?,c,function,pointers,pass-by-reference,C,Function,Pointers,Pass By Reference,这两个函数都填充了TCHAR sStringA和sStringB。问题是,在返回结果时,哪一个是首选的和更有效的 #include <tchar.h> #include <Windows.h> void FunctionA(TCHAR *sString1, DWORD dwLen) { _tcscpy_s(sString1, dwLen, L"String1"); return; } void FunctionB(TCHAR **sString2, DWORD dw

这两个函数都填充了TCHAR sStringA和sStringB。问题是,在返回结果时,哪一个是首选的和更有效的

#include <tchar.h>
#include <Windows.h>

void FunctionA(TCHAR *sString1, DWORD dwLen)
{
_tcscpy_s(sString1, dwLen, L"String1");

return;
}

void FunctionB(TCHAR **sString2, DWORD dwLen)
{
*sString2 = (TCHAR*)calloc(dwLen, sizeof(TCHAR));
_tcscpy_s(*sString2, dwLen, L"String2");

return;
}

int main()
{
TCHAR *sStringA = (TCHAR*)calloc(100, sizeof(TCHAR));
TCHAR *sStringB = NULL;

FunctionA(sStringA, 100);
FunctionB(&sStringB, 100);

free(sStringA);
free(sStringB);
}

function
稍微更有效,因为它的解引用更少。

将指针传递到指针的成本不太可能比将指针传递到
TCHAR
的成本更高。在性能方面,两个备选方案之间唯一的显著区别是B执行一个额外的(
&
)地址和一个解引用(一元
*
)操作,尽管这在原则上会使B的成本稍微高一点,但差异不太明显

当然,编译器可以将两个调用优化为完全相同的代码。它甚至可能优化掉
calloc()
调用,尽管这不太可能


总的来说,你不太可能花时间专注于这种微优化,除非你通过测量确定包含它们的代码部分太慢,并且你找不到算法改进,您有理由相信您试图优化的特定操作对代码的成本有很大的贡献。

这里的主要消费者是calloc,而不是call FunctionA/B本身。当您对代码进行基准测试和分析时,您的结果是什么?另一种可能是
TCHAR*FunctionD(DWORD dwLen)
TCHAR*sStringD=FunctionD(100)
调用,这样可以减少解引用和参数推送。我无法可靠地找到任何一个比其他任何一个都快的,与
calloc
要求相比差异很小。您的编译器没有内联它们吗?使用VS 2017。选项有默认、禁用、仅内联、任何合适的。“Default”是默认选项。我只是不想将整个字符串传递给函数。另外,我在上面创建了FunctionC,它的dwLen始终为0?@JeffR,您没有将字符串(数组)传递给任何函数。你不能-,C没有一个机制可以让你这么做。特别是,对
function()
的调用传递了一个指针。@Jeff,对于
FunctionC
,它不使用第二个参数的传入值,因此该值是无关的。由于调用了
\u tcslen()
函数,该函数的成本稍高一些,但您可以重写以避免需要该函数,或者编译器可能会对其进行优化。在任何情况下,如果通过这种方式分配更少的内存,那么该版本可以更有效地使用内存,但是没有理由期望它比其他版本运行得更快。
void FunctionC(TCHAR **sString2, DWORD dwLenOut)
{
    TCHAR sString[] = L"String2";
    dwLenOut = (DWORD) _tcslen(sString) + 1;
    *sString2 = (TCHAR*)calloc(dwLenOut, sizeof(TCHAR));
    _tcscpy_s(*sString2, dwLenOut, sString);

    return;
}

int main()
{
    TCHAR *sStringC = NULL;
    DWORD dwLen = 0;
    FunctionC(&sStringC, dwLen);
}