Reputation: 11
I used to code in C a long time ago and I seem to have lost my chops.
I am experiencing some odd behavior with a dynamic char *
array. I have a curses window (implemented in another file) that is to display a list of strings of active CU and TTY devices on my local machine. I attempt to zero-initialize a char **
array with calloc
, and then grow it by one appropriate size each time (dir->d_name
) matches my string comparisons.
The problem is that these strings display half the time upon running the program, and the other half of the time they are garbled or blank.
I suspect this is a memory/pointer issue related to either malloc()
or calloc()
, but I have been unable to pinpoint my misunderstanding for several days. Here is the code:
#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();
}
Thank you for your time/attention.
Upvotes: 1
Views: 46
Reputation: 211710
The biggest problem here is that you're not copying the dir
d_name
buffer. As the manual says:
The data returned by
readdir()
may be overwritten by subsequent calls toreaddir()
for the same directory stream.
This means you need to explicitly copy it:
devices[count-1] = strdup(dir->d_name);
That should eliminate a lot of the garbling.
Upvotes: 2