【问题标题】:Strange behavior with dynamic char ** in CC中动态char **的奇怪行为
【发布时间】:2017-12-13 01:52:02
【问题描述】:

我很久以前用 C 编写代码,但我似乎已经失去了我的能力。

我在使用动态 char * 数组时遇到了一些奇怪的行为。我有一个 curses 窗口(在另一个文件中实现),用于在我的本地计算机上显示活动 CU 和 TTY 设备的字符串列表。我尝试使用callocchar ** 数组进行零初始化,然后每次(dir->d_name)与我的字符串比较匹配时将其增大一个适当的大小。

问题是这些字符串在运行程序时显示一半的时间,而另一半的时间它们是乱码或空白。

我怀疑这是与malloc()calloc() 相关的内存/指针问题,但我几天来一直无法确定我的误解。代码如下:

#include <stdio.h>
#include "funcs.h"
#include <ncurses.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>

#define arraysize(ar) sizeof(ar)/sizeof(ar[0])

int main(void) 
{
    char ch;
    const char tty[4] = "tty.";
    const char cu[3] = "cu.";
    const char *directory = "/dev/";
    const char **devices = calloc(0,sizeof(const char *));

    // Initial device list gen //

    DIR *d;
    struct dirent *dir; 
    int count=0;
    d = opendir(directory); 
    if (d != NULL)
    {
        while((dir = readdir(d)))
        {
            if(strncmp(dir->d_name,tty,4)==0 || strncmp(dir->d_name,cu,3)==0)
            {
                count++;
                devices = realloc(devices,(count+1)*sizeof(const char *));
                devices[count-1] = (dir->d_name);
            }   
        }
        closedir(d);    
    }
printf("\n%d\n",count);

struct display MAIN = screen_init();

// Display List //

list_devices(devices,count,MAIN.devpad);
while(ch != 'q')
{
    ch = getch();
}
endwin();
}

感谢您的时间/关注。

【问题讨论】:

  • 你为什么要分配零?这是没有意义的。在这里使用realloc 非常麻烦。为什么不分配更大的块以避免如此频繁地敲击分配器?
  • 和设置指针为NULL不一样吗?
  • 你可能应该将它设置为NULL,直到你准备好分配一些东西。您可能会发现一个简单的链表是存储所有这些数据的更好方法,您可以轻松附加节点而无需重新分配。
  • 也不清楚为什么devices_fixed 甚至会影响这里。当您已经为它们分配了内存时,这有什么用?
  • 你绝对正确......那是我调试的尝试,我似乎发布了错误的版本。我道歉。之前的一切都是一样的,通常,设备被传递给我的绘图函数。不过,链表的建议是个好主意,谢谢!编辑:我已将上面的代码更新为预期版本。

标签: c arrays dynamic malloc realloc


【解决方案1】:

这里最大的问题是您没有复制dir d_name 缓冲区。正如手册所说:

readdir() 返回的数据可能会被后续对同一目录流的readdir() 调用覆盖。

这意味着你需要明确地复制它:

devices[count-1] = strdup(dir->d_name);

这应该消除了很多乱码。

【讨论】:

  • 就是这样!我知道这很愚蠢——我应该更多地关注我对 readdir() 的使用,而不是像那样拼凑它。非常感谢您的快速帮助 - 谢谢!编辑:我无法投票赞成你的答案。
  • 没问题!仔细阅读任何功能的文档总是值得的。通常会有一些棘手的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-29
  • 2012-06-01
相关资源
最近更新 更多