【问题标题】:realloc fails when printf is in code / weird chars当 printf 在代码/奇怪的字符中时 realloc 失败
【发布时间】:2023-01-19 23:38:09
【问题描述】:

我尝试为学校编写一个简单的 ls 实现

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
int normalsort( const void *string1, const void *string2) {
    char *const *char1 = string1;
    char *const *char2 = string2;
    return strcasecmp(*char1, *char2);
}

int listDir (char* path, int listToggeled, int classifyToggeled){
    DIR *dir = opendir(path);
    struct dirent *entry;
    struct stat s;
    char** listofentries;
    char symbol = '-';
    int counter = 0;





    while ((entry = readdir(dir)) != NULL){
        if (entry->d_name[0] != '.'){
            listofentries = realloc(listofentries, (counter + 1) * sizeof(char*));
            listofentries[counter] = entry->d_name;
            counter++;
        }
    }

    qsort(listofentries, counter, sizeof(char*), normalsort);

    for (int i = 0; i < counter; i++){
        char* entryname = listofentries[i];
        if (entryname[0] != '.'){
            printf("%s", entryname);

            if (classifyToggeled == 1){
                lstat(entryname, &s);

                if (S_ISDIR(s.st_mode)) {
                    symbol = '/';
                } else if (S_ISLNK(s.st_mode)) {
                    symbol = '@';
                } else if ((S_ISREG(s.st_mode)) && (s.st_mode & S_IXUSR)) {
                    symbol = '*';
                } else {
                    symbol = ' ';
                }

                printf("%c", symbol);
            }

            if (listToggeled == 1){
                printf("\n");
            }
            else {
                printf("  ");
            }
        }
    }
    closedir(dir);
    return 0;
}

int main(int argc, char **argv) {
    int classifyToggeled = 0;
    int listToggeled = 0;
    char* dirToList = ".";

    if (argc == 1){
        listDir(dirToList, listToggeled, classifyToggeled);
        return 0;
    }
    for (int i = 1; i < argc; i++){
        char* currentArg = argv[i];

        //Check if -F is set
        if (strcmp(currentArg, "-F") == 0 || strcmp(currentArg, "-1F") == 0 || strcmp(currentArg, "-F1") == 0){
            classifyToggeled = 1;
        }

        //Check if -1 is set
        if (strcmp(currentArg, "-1") == 0 || strcmp(currentArg, "-1F") == 0 || strcmp(currentArg, "-F1") == 0){
            listToggeled = 1;
        }

        //List out all folders
        if (currentArg[0] != '-'){
            dirToList = currentArg;
        }

    }
    //If no folders were listed yet, list current folder
    //printf("dirtolist: %s", dirToList); <-- This line
    listDir(dirToList, listToggeled, classifyToggeled);
    if (listToggeled == 0){
        printf("\n");
    }
    return 0;
}

它有一些错误:

  • 当上面标记的printf行没有被注释掉时,程序告诉realloc(): invalid old size
  • 当此行被注释掉时,只有在没有任何参数的情况下执行程序时才会发生这种情况
  • /bin/ 和 /sbin/ 打印出奇怪的字符

我认为这是某种内存问题,但我几乎没有任何 C 知识可以看到它

【问题讨论】:

  • 检查opendir、lstat和realloc的返回值。
  • 显示的代码在将它传递给realloc之前似乎没有初始化listofentries。

标签: c memory realloc ls


【解决方案1】:

来自 C11:

realloc 函数解除分配 ptr 和指向的旧对象 返回一个指向新对象的指针,该对象的大小由 size 指定。....如果 ptr 与之前由内存返回的指针不匹配 管理功能,或者如果空间已通过调用释放 free 或 realloc 函数,行为未定义。

您的代码表现出未定义的行为,因为您将非静态未初始化指针传递给了内容不确定的 realloc。

realloc 函数返回一个指向新对象的指针(可能 与指向旧对象的指针具有相同的值)或空指针 如果无法分配新对象。

可能的修复:

  • 用0 / NULL 初始化它。
  • 声明为static。
  • 将其替换为拨打malloc。

realloc 函数返回一个指向新对象的指针(可能 与指向旧对象的指针具有相同的值)或空指针 如果无法分配新对象。

realloc 在失败时返回 NULL,您的代码应该检查它。

【讨论】:

    【解决方案2】:

    错误:

    • listofentries 未初始化,必须设置为 NULL 否则不能使用 realloc。
    • 您没有检查 realloc 是否成功。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-10
      • 2021-05-14
      • 1970-01-01
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      相关资源
      最近更新 更多