Reputation: 99
Working in c. I am trying to dynamically allocate an array that is within a struct. The array will hold rows of char data. I can't see any errors, any help is appreciated.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct data
{
char **d;
}Data;
int main(void)
{
Data *a = malloc(10*sizeof(Data));
int i = 0, length = 0;
for(i = 0; i < 10; i++)
{
char buffer[1000] = { '\0' };
printf("\nenter data\n");
fgets(buffer, 1000, stdin);
length = strlen(buffer);
a[i].d[i] = malloc(sizeof(length+1)); //errors here, unhandled exception
strcpy(a[i].d[i], buffer);
}
for (i = 0; i < 10; i++)
{
printf("%s", a[i].d[i]);
}
return 0;
}
Upvotes: 1
Views: 1129
Reputation: 46960
First, the
malloc(sizeof(length+1));
makes no sense. You mean
malloc(length+1);
malloc
allocates in units of char
s. The sizeof()
operator returns the size in char
s of the type or object that is it's argument. length+1
is not a suitable argument.
Next, you seem to mean to be reading an array of strings. The struct is not contributing much to the problem solution. Consider throwing out the structs and using just an array of pointers to characters (i.e. an array of strings of varying lengths), or else keep the structs and change the field to a char*
type.
Additionally, if you don't know the number of strings in the file in advance, then you must grow the array dynamically with something like realloc()
.
Here is the array of strings approach:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF_SIZE 1000
int main(void)
{
int i, n, n_max = 8;
char **a = malloc(n_max * sizeof(char*));
for(n = 0; ; ++n)
{
char buffer[BUF_SIZE + 1]; // zeroing buffer is a waste with fgets
printf("\nenter data or Ctrl-Z to stop\n");
if (!fgets(buffer, sizeof(buffer), stdin)) return;
if (n >= n_max) {
n_max *= 2;
a = realloc(a, n_max * sizeof(char*));
}
a[n] = malloc(strlen(buffer) + 1);
strcpy(a[n], buffer);
}
// n now contains number of strings actually read
for (i = 0; i < n; i++)
{
printf("%s", a[i]);
}
return 0;
}
Upvotes: 0
Reputation: 754
Since char **d
is a pointer to a pointer. And malloc returns void*
type !
Hence,
type mismatch is there.
You have to first allocate the array of pointers. That is a[i].d=malloc(row*sizeof(char *);
Then you can do a[i].d[i] = malloc((length+1)*sizoef(char));
Upvotes: 1
Reputation: 361546
a[i].d[i]
The double use of i
here is a red flag. This should be either a[i].d
or a.d[i]
. It looks like you're intending to store 10 strings, one per Data
object. In that case, your struct declaration should contain char *
not char **
.
typedef struct data {
char *d;
} Data;
And then the lines assigning to d
would become:
a[i].d = malloc(length + 1);
strcpy(a[i].d, buffer);
That gets rid of the double [i]
indices. Each Data
object contains one string named d
. In the loop, you allocate memory for that string and then copy buffer
into d
. All good!
Notice also that I've gotten rid of the sizeof
inside the malloc() call. You want to allocate length + 1
characters. No need for sizeof
. If you want to be more explicit you could change length + 1
into (length + 1) * sizeof(char)
—but you don't have to, because sizeof(char)
is always 1.
Upvotes: 0