简体   繁体   English

将const char *传递给函数时丢失数据

[英]Losing data when passing const char* to function

I've been having a problem with some c code for a few days now, I've looked everywhere but I'm not sure how to fix it and it's driving me crazy! 几天来,我一直在遇到一些c代码的问题,到处都是,但是我不确定如何解决它,这使我发疯! Basically what happens is that function _getfile() gets a relative/absolute filepath from argv[1] (presumed it is available) and checks if an absolute filepath exists and if the file can be opened and read. 基本上发生的是函数_getfile()argv[1]获取相对/绝对文件路径(假定它可用),并检查是否存在绝对文件路径以及是否可以打开和读取文件。 The function then returns that filepath to main and stores it as a const char* . 然后,该函数将该文件路径返回给main并将其存储为const char* Up to here, everything works fine. 到这里,一切正常。 No data loss or problems. 没有数据丢失或问题。 But as soon as I pass filepath to any other function, my program starts doing crazy things. 但是,一旦我将文件filepath传递给任何其他函数,我的程序就会开始做疯狂的事情。 filepath is either turned into a bunch of \\n characters or part of it's just missing. filepath要么变成一堆\\n字符,要么只是一部分丢失。 Here's the code: 这是代码:

#include <limits.h> //PATH_MAX
#include <unistd.h> //access()
#include <stdio.h>
#include <stdlib.h>

const char* _getfile(int argcount, const char ** argvars) {
    //Check if filepath has been given as console parameter
    if (argcount == 1) {
        exit(EXIT_FAILURE);
    }

    //Get absolute path of given filepath
    const char* relpath = argvars[1];
    char buffer[PATH_MAX + 1];
    const char* abspath = realpath(relpath, buffer);

    //Check if an absolute path could be found
    if (abspath) {
        printf("Source at '%s'.\n", abspath);
    } else {
        printf("No absolute filepath could be found for '%s'.\n", relpath);
        exit(EXIT_FAILURE);
    }

    //Check if file exists
    if(access(abspath, F_OK) != -1) {
        //Check file for read permissions
        if (access(abspath, R_OK) != -1) {
            return abspath;
        } else {
            printf("'%s' couldn't be accessed as it lacks read permissions.\n", abspath);
            exit(EXIT_FAILURE);
        }
    } else {
        printf("'%s' doesn't exist.\n", abspath);
        exit(EXIT_FAILURE);
    }
}

void _readfile(const char* filename) {
    //'filename' has now been changed!
    FILE* file = NULL;
    file = fopen(filename, "r");
    /*
    Read/print file contents etc.
    ...
    */

int main(int argc, const char** argv) {
    const char* filepath = _getfile(argc, argv);
    _readfile(filepath);
    return 0;

So say I pass "/Users/Token/Desktop/Test.txt" as a parameter in the console. 因此说我在控制台"/Users/Token/Desktop/Test.txt"作为参数传递。 When the absolute filepath is returned to main, namely still "/Users/Token/Desktop/Test.txt" , everything's fine. 当绝对文件路径返回到main时,即仍然是"/Users/Token/Desktop/Test.txt" ,一切都很好。 When I pass it to _readfile() , inside of the function the filepath is now something like "\\n\\n\\n\\n\\n\\n..." or "/Users/To" and the rest of it is missing. 当我将其传递给_readfile() ,在函数内部,文件路径现在类似于"\\n\\n\\n\\n\\n\\n...""/Users/To" ,其余部分均丢失。 It looks like a memory leak to me, but I can't find what I'm doing wrong. 对我来说,这似乎是内存泄漏,但是我找不到我做错的事情。 Also buffer seems to hold 1025 characters on my machine the last time I checked in the debugger, so that can't be the problem. 另外,上次我在调试器中签入buffer似乎在我的计算机上保留了1025个字符,所以这不是问题。 I don't think this matters, but I'm using XCode on OS X El Capitan 10.11.13. 我认为这无关紧要,但是我在OS X El Capitan 10.11.13上使用XCode。 Appreciating all help in advance! 提前感谢所有帮助!

realpath resolves string passed to it and stores output in buffer passed as second argument realpath解析传递给它的字符串,并将输出存储在作为第二个参数传递的缓冲区中

char buffer[PATH_MAX + 1];
const char* abspath = realpath(relpath, buffer);
//                                       ^^^
//                                in your case here

which is local variable in your code. 这是您代码中的局部变量。 As an array put on stack it becomes illegal to try to access it as soon as your function returns, and it happens before the caller even touches the something wished-to-be-returned-but-dissapeared. 当数组放到堆栈上时,一旦函数返回就试图访问它是非法的,并且发生在调用者甚至未触摸希望返回但不满意的内容之前。

Solution: 解:

Pass the preallocated buffer for resulting string into _getfile: 将用于结果字符串的预分配缓冲区传递到_getfile中:

const char *
_getfile(int argcount, const char ** argvars, char* buf)
{
    const char* relpath, *abspath;

    relpath = argvars[1];
    abspath = realpath(relpath, buffer);
    if (abspath != NULL)
    {
        // OK
        return abspath;
    } else {
        // handle
    }

You are trying to return a local pointer. 您正在尝试返回本地指针。 This will never work as when the function goes out of scope, all the local variables are destroyed. 当函数超出范围时,这将永远无法工作,所有局部变量都将被销毁。 So the return value will have garbage as you are seeing. 因此,返回值将出现垃圾。

You can do one of two things: 您可以执行以下两项操作之一:

  1. Add an argument to the function which takes the return value. 向该函数添加一个参数,该参数采用返回值。
  2. Define the return value in heap. 在堆中定义返回值。 (This is a bad approach, because in general, the calling code is responsible for allocating and deallocating heap memory. If you allocated the memory in this function, and deallocated it outside, its just bad programming :)) (这是一种不好的方法,因为通常,调用代码负责分配和取消分配堆内存。如果您在此函数中分配了内存,并在外部释放了内存,那将是很糟糕的编程:))

You call realpath with a buffer which is locally allocated variable within your _getfile function. 您可以使用_getfile函数中本地分配的buffer来调用realpath It gets destroyed when you return from your function and it is no longer valid. 当您从函数中返回时,它将被销毁,并且不再有效。 Thus you get weird values here. 因此,您在这里得到了奇怪的值。 Use NULL as a second argument to the realpath call, so you'll get the pointer to the newly allocated buffer. NULL用作realpath调用的第二个参数,因此您将获得指向新分配的缓冲区的指针。 After using it don't forget to free it. 使用它后,别忘了free它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM