Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers C-错误为;free():无效的下一个大小(正常)";_Pointers_Gdb_Valgrind_Sigabrt - Fatal编程技术网

Pointers C-错误为;free():无效的下一个大小(正常)";

Pointers C-错误为;free():无效的下一个大小(正常)";,pointers,gdb,valgrind,sigabrt,Pointers,Gdb,Valgrind,Sigabrt,我就是找不到造成这个问题的原因 MYSQL *startup(unsigned char *path_to_file, int size_of_path) { MYSQL *con; bool path_is_file = false; bool path_is_directory = false; FILE *startup_file; int i; unsigned char buffer[LINEBUFFERSIZE]; unsigned char string[LINEBUFFERSIZ

我就是找不到造成这个问题的原因

MYSQL *startup(unsigned char *path_to_file, int size_of_path) {
MYSQL *con;
bool path_is_file = false;
bool path_is_directory = false;
FILE *startup_file;
int i;
unsigned char buffer[LINEBUFFERSIZE];
unsigned char string[LINEBUFFERSIZE];
unsigned char c;

//Allocate memory for the new file path
unsigned char *path;
path = (unsigned char *) malloc(size_of_path);
if(path == NULL)
    error("Could not allocate memory for path to file.\nIn startup()\n");

//Check if startup file exists or if it is a directory
//Bug is somewehre here!!!!
struct stat s;
printf("%s", path_to_file);
if(stat(path_to_file, &s) == 0) {
    if(s.st_mode & S_IFDIR) {
        //It's a directory
        path_is_directory = true;
        //Add the standard startup file name to the directory
        path = (unsigned char *) realloc(path, size_of_path + sizeof(STARTUP_FILE));
        if(path == NULL)
            error("Could not reallocate memory for variable path.\nIn startup()\n");
        //Put the strings together
        sprintf(path, "%s/%s", path_to_file, STARTUP_FILE);
    }
    else if(s.st_mode & S_IFREG) {
        //It's a file
        path_is_file = true;
        path = path_to_file;
    }//End else if
    else //Someting else. abort
        error("Given file is neither file or directory.\nIn startup()\n");
}
else //Error
    error("Error in looking up type of path.\nIn startup()\n");;


//Check if the startup file exists
fprintf(stderr, "%s\n", path);
if((startup_file = fopen(path, "r")) == NULL) {
    //File does not exist, create a basics one for the user to modify
    if((startup_file = fopen(path, "w+")) == NULL)
        error("Could not create the startup file.\n");
    //Write the standard text to the new file, so the user can modify it
    //sizeof(STARTUP_FILE_TEXT)-1 as gedit cries if there is a terminator at the end
    fwrite(STARTUP_FILE_TEXT, sizeof(STARTUP_FILE_TEXT[0]), sizeof(STARTUP_FILE_TEXT)-1, startup_file);
}//End outer if


//Read from the startup file and find out which tables and database are needed and may have to be created
//While loop will run although if file was just created, fix it
section current;
while(fgets(buffer, sizeof(buffer), startup_file) != NULL) {
    if(strcmp(buffer, "[DATABASES]")) {
        //Every line now should contain the name of dbs, until new section
        current = DATABASES;
    }
    else if(strcmp(buffer, "[TABLES]")) {
        //Every line now should contain the name of dbs, until new section
        current = TABLES;
    }
    else {
        //Read the lines and create the table or database
        //Ignore everything behind #
        //Just numbers and letters are allowed
        //Read one line and save it into buffer
        //What happens, if the line exceeds buffer length and is split into to?
        //Process every character, but do not exceed the buffers limit (also save one for the '\0' termiantor)
        for(i = 0; i < (sizeof(buffer)-1); i++) {
            //Allowed characters are: A-Z, a-z, 0-9, dash, underscore and space
            //Read until '\n' or '#' or if not allowed characters are used print error and do not use it
            c = buffer[i];
            if(isalnum(c) || (c == '-') || (c == '_') || (c == ' '))  {
                //Correct
                string[i] = c;
            }//End if
            else if(c == '\n' || c == '\0') {
                //End of line or end of string, not checking for EOF as fgets already does it \
                and it would requried the int data type
                break;
            }//End else if
            else {
                //Wrong, stop
                printf("Wrong character used in setup file.\nWrong characters was: %c\n", c);
                break;
            }//End else
        }//End for
        //Add terminator at the end
        string[i] = '\0';
        //Create table or database
        switch(current) {
            case DATABASES:
                create_db(string, sizeof(string));
                break;
            case TABLES:
                break;
            default:
                break;
        }//End switch

    }
}//End while

//Create db and then open the database as a specific user
//create_db();
con = open_db("user1", "passwd", "Vocables");

//Clean up
fclose(startup_file);
free(path);
return con;
}
在gdb中执行单行时,您会在错误发生之前缩短:

    26              path_is_directory = true;
(gdb) n
28              path = (unsigned char *) realloc(path, size_of_path + sizeof(STARTUP_FILE));
(gdb) n
29              if(path == NULL)
(gdb) n
32              sprintf(path, "%s/%s", path_to_file, STARTUP_FILE);
(gdb) n
51      fprintf(stderr, "%s\n", path);
(gdb) n
/home/linux/Cloud/Decrypted/Porifera-Server//startup.txt
52      if((startup_file = fopen(path, "r")) == NULL) {
(gdb) n
当我在第52行之后执行下一行时,问题就出现了

使用“valgrind--leak check=yes./Porifera Server 8080~/Cloud/Decrypted/Porifera Server”,它实际上运行正常。但却有一大堆“错误”:


我就是找不到它;其他出现类似错误的人要么在
fopen
函数的文件路径中有“\n”,要么没有初始化ptr,但试图释放它。自上次运行以来,我没有接触过任何ptr自由功能,目前我还没有找到导致此问题的ptr。

当遇到错误时,请从1开始。第一,它可能是以下错误的原因

MYSQL *startup(unsigned char *path_to_file, int size_of_path) {
MYSQL *con;
bool path_is_file = false;
bool path_is_directory = false;
FILE *startup_file;
int i;
unsigned char buffer[LINEBUFFERSIZE];
unsigned char string[LINEBUFFERSIZE];
unsigned char c;

//Allocate memory for the new file path
unsigned char *path;
path = (unsigned char *) malloc(size_of_path);
if(path == NULL)
    error("Could not allocate memory for path to file.\nIn startup()\n");

//Check if startup file exists or if it is a directory
//Bug is somewehre here!!!!
struct stat s;
printf("%s", path_to_file);
if(stat(path_to_file, &s) == 0) {
    if(s.st_mode & S_IFDIR) {
        //It's a directory
        path_is_directory = true;
        //Add the standard startup file name to the directory
        path = (unsigned char *) realloc(path, size_of_path + sizeof(STARTUP_FILE));
        if(path == NULL)
            error("Could not reallocate memory for variable path.\nIn startup()\n");
        //Put the strings together
        sprintf(path, "%s/%s", path_to_file, STARTUP_FILE);
    }
    else if(s.st_mode & S_IFREG) {
        //It's a file
        path_is_file = true;
        path = path_to_file;
    }//End else if
    else //Someting else. abort
        error("Given file is neither file or directory.\nIn startup()\n");
}
else //Error
    error("Error in looking up type of path.\nIn startup()\n");;


//Check if the startup file exists
fprintf(stderr, "%s\n", path);
if((startup_file = fopen(path, "r")) == NULL) {
    //File does not exist, create a basics one for the user to modify
    if((startup_file = fopen(path, "w+")) == NULL)
        error("Could not create the startup file.\n");
    //Write the standard text to the new file, so the user can modify it
    //sizeof(STARTUP_FILE_TEXT)-1 as gedit cries if there is a terminator at the end
    fwrite(STARTUP_FILE_TEXT, sizeof(STARTUP_FILE_TEXT[0]), sizeof(STARTUP_FILE_TEXT)-1, startup_file);
}//End outer if


//Read from the startup file and find out which tables and database are needed and may have to be created
//While loop will run although if file was just created, fix it
section current;
while(fgets(buffer, sizeof(buffer), startup_file) != NULL) {
    if(strcmp(buffer, "[DATABASES]")) {
        //Every line now should contain the name of dbs, until new section
        current = DATABASES;
    }
    else if(strcmp(buffer, "[TABLES]")) {
        //Every line now should contain the name of dbs, until new section
        current = TABLES;
    }
    else {
        //Read the lines and create the table or database
        //Ignore everything behind #
        //Just numbers and letters are allowed
        //Read one line and save it into buffer
        //What happens, if the line exceeds buffer length and is split into to?
        //Process every character, but do not exceed the buffers limit (also save one for the '\0' termiantor)
        for(i = 0; i < (sizeof(buffer)-1); i++) {
            //Allowed characters are: A-Z, a-z, 0-9, dash, underscore and space
            //Read until '\n' or '#' or if not allowed characters are used print error and do not use it
            c = buffer[i];
            if(isalnum(c) || (c == '-') || (c == '_') || (c == ' '))  {
                //Correct
                string[i] = c;
            }//End if
            else if(c == '\n' || c == '\0') {
                //End of line or end of string, not checking for EOF as fgets already does it \
                and it would requried the int data type
                break;
            }//End else if
            else {
                //Wrong, stop
                printf("Wrong character used in setup file.\nWrong characters was: %c\n", c);
                break;
            }//End else
        }//End for
        //Add terminator at the end
        string[i] = '\0';
        //Create table or database
        switch(current) {
            case DATABASES:
                create_db(string, sizeof(string));
                break;
            case TABLES:
                break;
            default:
                break;
        }//End switch

    }
}//End while

//Create db and then open the database as a specific user
//create_db();
con = open_db("user1", "passwd", "Vocables");

//Clean up
fclose(startup_file);
free(path);
return con;
}
==17917== Invalid write of size 8
==17917==    at 0x5E53E04: __GI_mempcpy (in /usr/lib/libc-2.21.so)
==17917==    by 0x5E44BDD: _IO_default_xsputn (in /usr/lib/libc-2.21.so)
==17917==    by 0x5E18C61: vfprintf (in /usr/lib/libc-2.21.so)
==17917==    by 0x5E3AC2A: vsprintf (in /usr/lib/libc-2.21.so)
==17917==    by 0x5E1F266: sprintf (in /usr/lib/libc-2.21.so)
==17917==    by 0x401647: startup (server_func.c:32)
==17917==    by 0x4012BB: main (server.c:23)
==17917==  Address 0x6c8709e is 14 bytes inside a block of size 20 alloc'd
==17917==    at 0x4C2C29E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17917==    by 0x40160B: startup (server_func.c:28)
==17917==    by 0x4012BB: main (server.c:23)
在这个堆栈跟踪中,interesting片段是程序的代码,因为我们可以假设运行时/标准库中的代码可以工作

Valgrind在这里告诉您两件事:

  • 在文件服务器_func.c第32行的启动函数中,您正在访问不应该访问的内存(大小为8的无效写入)
  • 您正在访问的内存超过了您在server_func.c第28行分配的20个字节的缓冲区14个字节
  • 第28行:
    path=(unsigned char*)realloc(路径,路径的大小+sizeof(启动文件))

    第32行:
    sprintf(路径,“%s/%s”,路径到文件,启动文件)

    所以在第28行中,您没有为“/”分隔符分配空间,也可能没有为nul终止符分配空间

    您还需要确保路径的
    size\u
    是正确的,并且
    sizeof(STARTUP\u FILE)
    为您提供了正确的大小,如果
    STARTUP\u FILE
    是一个字符数组,它将提供正确的大小,但是如果它是一个字符指针,它将是错误的。也许您需要使用strlen(启动文件)


    假设
    size\u of_path
    是正确的,您可能需要将缓冲区大小计算为
    size\u of_path+strlen(启动文件)+2

    这表示您使用realloc()创建的缓冲区太小,因此下面的
    sprintf(路径,“%s/%s”,路径到启动文件,启动文件)可能会破坏内存。但是,我们不知道sizeof(STARTUP_FILE)或size_of_path是什么,也不知道它们是否正确-也许STARTUP_FILE是一个char*但您假设它是一个数组。不过,您需要为“/”和nul终止符分配空间。是的,您是对的,尽管我确信分配了足够的内存。但这解决了问题。您能告诉我您是如何发现的吗?或者引用gdb或valgrind输出的行,以便下次我知道,因为我仍然是初学者。:-)我使用了sizeof(argv[2]),但它返回的长度绝对错误。有没有办法找出命令行参数的大小?是的,strlen(argv[2])给出了长度,不包括nul终止符。H,感谢您的解释:-)当我使用sizeof(argv[2])来找出它时,路径的大小是不正确的,但它是一个字符指针,所以我将它改为strlen(argv[2]):-)
    
    ==17917== Invalid write of size 8
    ==17917==    at 0x5E53E04: __GI_mempcpy (in /usr/lib/libc-2.21.so)
    ==17917==    by 0x5E44BDD: _IO_default_xsputn (in /usr/lib/libc-2.21.so)
    ==17917==    by 0x5E18C61: vfprintf (in /usr/lib/libc-2.21.so)
    ==17917==    by 0x5E3AC2A: vsprintf (in /usr/lib/libc-2.21.so)
    ==17917==    by 0x5E1F266: sprintf (in /usr/lib/libc-2.21.so)
    ==17917==    by 0x401647: startup (server_func.c:32)
    ==17917==    by 0x4012BB: main (server.c:23)
    ==17917==  Address 0x6c8709e is 14 bytes inside a block of size 20 alloc'd
    ==17917==    at 0x4C2C29E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17917==    by 0x40160B: startup (server_func.c:28)
    ==17917==    by 0x4012BB: main (server.c:23)