在执行malloc之后将字符串传递给函数

在执行malloc之后将字符串传递给函数,c,C,这是我的主C函数中的代码 char *filename; filename = malloc(2001); //if I don't do this step it gives me an error filename = ListDirectoryContents("test_data\\tmp");//this returns a string for filename printf("filename : %s ", filename);//value of

这是我的主C函数中的代码

char *filename;            

filename = malloc(2001); //if I don't do this step it gives me an error

filename = ListDirectoryContents("test_data\\tmp");//this returns a string  for filename

printf("filename : %s ", filename);//value of filename is displayed which is an address and is NOT NULL OR EMPTY

copyObjectFileInINfolder(filename, logger);//here I am passing the filename to this function where I am getting the error
现在我要做的是将字符串文件名传递到函数中(在函数中,文件名的变量是object)

但当我传递它时,它总是空的,即filename/object不显示任何值,甚至不显示“(null)”。我知道这可能与这个malloc命令有关

这是另一个函数

char* ListDirectoryContents(const char *sDir)
{
WIN32_FIND_DATA fdFile;
HANDLE hFind = NULL;

char sPath[2000];

//Specify a file mask. *.* = We want everything!
sprintf(sPath, "%s\\*.*", sDir);

if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
{
    printf("Path not found: [%s]\n", sDir);
    return 1;
}

do
{
    //Find first file will always return "."
    //    and ".." as the first two directories.
    if(strcmp(fdFile.cFileName, ".") != 0
            && strcmp(fdFile.cFileName, "..") != 0)
    {
        //Build up our file path using the passed in
        //  [sDir] and the file/foldername we just found:
        sprintf(sPath, "%s\\%s", sDir, fdFile.cFileName);

        //Is the entity a File or Folder?
        if(fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
        {
            printf("Directory: %s\n", sPath);
            ListDirectoryContents(sPath); //Recursion, I love it!
        }
        else{
            printf("File: %s\n", sPath);
            FindClose(hFind);
            return sPath;
        }
    }
   }while(FindNextFile(hFind, &fdFile)); //Find the next file.

FindClose(hFind); //Always, Always, clean things up!

    return "";
}
您有两个问题:第一个问题非常明显,那就是重新分配
filename
会使您丢失原始指针

另一个问题是,在
ListDirectoryContents
函数中,您返回一个指向局部变量
sPath
的指针,这将导致未定义的行为,因为一旦函数返回,该变量就不再存在

我可以看到两种可能的解决办法:

  • filename
    作为第二个参数传递给
    ListDirectoryContents
    函数,并使用该参数而不是
    sPath
  • 不要为
    filename
    分配内存,而是在
    ListDirectoryContents
    函数中动态分配
    sPath

  • 此外,无论您如何处理问题,当函数以某种方式失败时,通常都不会返回指向有效但为空的字符串的指针。相反,通常返回
    NULL


    哦,顺便说一句,
    ListDirectoryContents
    中的递归不会真正像你期望的那样工作,因为你不处理返回的值,你只是丢弃它。

    我几乎可以肯定你正在覆盖
    malloc()
    -ed内存。@SouravGhosh如何解决这个问题?告诉我们
    ListDirectoryContents()
    filename=malloc(2001);filename=ListDirectoryContents(“测试数据\\tmp”)毫无意义。马洛克在这里没用。如果在删除第一行时出现错误,那么您在某个地方有未定义的行为。是的-您所做的事情本质上是错误的。我会选择(2),因为调用者不知道需要多少空间,(这和注释/doc强调调用者对结果生命周期负责)。事实上,这几乎需要返回一些更复杂的“list”结构。
    
    char* ListDirectoryContents(const char *sDir)
    {
    WIN32_FIND_DATA fdFile;
    HANDLE hFind = NULL;
    
    char sPath[2000];
    
    //Specify a file mask. *.* = We want everything!
    sprintf(sPath, "%s\\*.*", sDir);
    
    if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
    {
        printf("Path not found: [%s]\n", sDir);
        return 1;
    }
    
    do
    {
        //Find first file will always return "."
        //    and ".." as the first two directories.
        if(strcmp(fdFile.cFileName, ".") != 0
                && strcmp(fdFile.cFileName, "..") != 0)
        {
            //Build up our file path using the passed in
            //  [sDir] and the file/foldername we just found:
            sprintf(sPath, "%s\\%s", sDir, fdFile.cFileName);
    
            //Is the entity a File or Folder?
            if(fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
            {
                printf("Directory: %s\n", sPath);
                ListDirectoryContents(sPath); //Recursion, I love it!
            }
            else{
                printf("File: %s\n", sPath);
                FindClose(hFind);
                return sPath;
            }
        }
       }while(FindNextFile(hFind, &fdFile)); //Find the next file.
    
    FindClose(hFind); //Always, Always, clean things up!
    
        return "";
    }