这是我的代码:
TCHAR *sResult = (TCHAR *) calloc(16384+1, sizeof(TCHAR));
sResult = (TCHAR *) GetValueFromFile(sFilename,L"Dept",L"Names"); // #1
_tcscpy(sResult,(TCHAR *) GetValueFromFile(sFilename,L"Dept",L"Names"); // #2
功能:
TCHAR *GetValueFromFile(TCHAR *sFilename,TCHAR *sDept,TCHAR *sNames)
{
...
}
哪个是正确的? #1或#2?
谢谢大家。 编辑#1:
我在.cpp文件中使用VS2008,但实际上只是C代码。
我只需要在GetValueFromFile中打开一个文件并返回返回的字符串。我应该在GVFF中分配内存并在我的程序中释放它吗?
main()
{
TCHAR *sResult;
DWORD dwRetVal = GetValueFromFile(sFile,L"Dept",L"Name", &sResult);
...
free(sResult);sResult=NULL;
}
喜欢这个吗?
DWORD GetValueFromFile(TCHAR *sFilename,TCHAR *sDept,TCHAR *sNames, TCHAR ** sValueData)
{
dwL = GetStringDataLength(…)
*sValueData = (TCHAR *) calloc(dwL+1, sizeof(TCHAR));
_tcscpy_s(sValueData,dwL,sDataFromFile);
}
答案 0 :(得分:2)
嗯,首先,在案例1中这是不必要的并导致问题:
TCHAR *sResult = (TCHAR *) calloc(16384+1, sizeof(TCHAR));
我不知道16384+1
来自哪里,所以我现在假设它是“正确的”,但你继续将指针设置为下一行中的另一个值。那个,我的朋友,是一个内存泄漏。你为什么要分配你不需要的内存?
您的问题实际上归结为GetValueFromFile
的实施。如果该函数返回一个指针(它确实),那么它肯定应该是一个有效的指针,你负责解除它(可能。再次,取决于实现)。
除非您确实需要副本,否则无需创建副本。您提供给我们的信息中没有“正确”或“错误”,我们需要了解GetValueFromFile
的详细信息。
根据你的编辑:
该功能不会返回任何内容。完全没有。它的签名表示它返回一个DWORD,而不是TCHAR*
。它显然不同于您的第一个示例,因为它将指针初始化为输出参数(第4个),但这不是您在原始示例中调用它的方式。
我现在只是进一步困惑,但是如果函数初始化指针,那么你只需要声明(函数外没有内存分配)指针和pas在它的地址。
鉴于
DWORD GetValueFromFile(TCHAR *sFilename,TCHAR *sDept,TCHAR *sNames, TCHAR ** sValueData)
然后传递指针的正确方法是:
TCHAR *result;
GetValueFromFile(filename, dept, names, &result);
该函数初始化您的result
变量以指向有效位置。 不要忘记您现在负责取消分配它!
答案 1 :(得分:0)
1显然不正确。首先使用calloc
分配空格,然后使用GetValueFromFile
的返回值覆盖该空间的点。假设没有干预代码将指针保存在其他地方,这意味着您不再能够访问您分配的内存,因此您无法再访问或释放它。简而言之,内存泄漏很大。
根据GetValueFromFile
如何分配返回指针的内存,#2可能同样糟糕,但您发布的代码并不足以让我们知道。如果它返回类似于指向静态分配缓冲区的指针,则可能是正确的(对于某些正确的定义)。如果它使用malloc
或calloc
之类的空间分配空间,并期望客户端代码在需要时释放它,那么它就会出现与#1类似的问题。
请注意,“对于某些正确的定义”基本上会转换为:“错误,只要您有多个线程,或任何需要重入”。鉴于当前多核和多处理器系统的普遍存在,这个定义现在非常狭窄,并且一直变得越来越窄。