I'm attempting to create a struct that has an array of char pointers as one of its members and am having trouble attempting to set/access elements of the array. Each char pointer is going to point to a malloc'd buffer. This is the struct currently.
struct rt_args {
long threadId;
char (*buffers)[];
FILE* threadFP;
};
And when I attempt to access an element of buffers via
char *buffer = malloc(100);
struct rt_args (*rThreadArgs) = malloc( sizeof(long) +
(sizeof(char *) * (numThreads)) +
sizeof(FILE*)
);
rThreadArgs->buffers[0] = buffer;
I get the error "invalid use of array with unspecified bounds". I don't know what the size of the array is going to be beforehand, so I can't hardcode its size. (I've tried de-referencing buffers[0] and and adding a second index? I feel as though its a syntactical error I'm making)
You can't have arrays without a size, just like the error message says, at least not n the middle of structures. In your case you might think about pointers to pointers to char? Then you can use e.g. malloc for the initial array and realloc when needed.
Something like
char **buffers;
Then do
buffers = malloc(sizeof(buffers[0]) * number_of_pointers_needed);
Then you can use buffers like a "normal" array of pointers:
buffers[0] = malloc(length_of_string + 1);
strcpy(buffers[0], some_string);
char (*buffers)[SIZE];
declares buffers as a pointer to char array not the array of pointers. I think you need this
char *buffers[SIZE];
NOTE: Flexible array member can be used only when it is the last member of the structure.
Related
Strait to the point.
I have a struct with a string, char and int.
The struct is created dynamically because i will need it in different parts of my program.
struct A
{
char staticString[20];
char* dynamicString;
char character;
int integer;
};
I know if i want to create a struct i call:
A example = (A)malloc(sizeof(A));
In order to populate the dynamicString and int i used:
example->dynamicString = (char*)malloc(sizeof(char*));
example->integer = (int)malloc(sizeof(int));
Unfourtanetly when i tried to populate staticString and char it didn't worked.
Don't even ask what was my code for those, i tried a lot of combinations from everywhere.
In addition to that can somebody show me examples how to write/read those values?
Thanks in advance.
First things first:
You're using C, and by the way you've defined the structure, you need to declare the pointer like so:
struct A *example;
Next, malloc returns a pointer, so you need to cast to a pointer (and not to a structure):
(struct A *)malloc(sizeof(struct A));
Secondly, I'm not sure why but hey:
- you're trying to dynamically allocate an int in the structure. As I said previously, malloc returns a pointer, so in your structure you need an int pointer like so "int *integer;"
- you're trying to allocate a dynamic string, however you're not doing it properly, here is what I think you want
example->dynamicString = (char *)malloc(sizeof(char) * 10);
Where 10 is the size of your dynamic string.
Edit:
you may also populate the integer in your struct statically or dynamically, but I think you intended the static approach:
example->integer = 123;
The dynamic approach would be (assuming you have int *integer in your struct):
example->integer = (int *)malloc(sizeof(int));
*(example->integer) = 123;
Every time you create a new struct the memory in the heap is set to size of :
sizeof(char)*20 + sizeof(char pointer) +sizeof(char)+ sizeof(int).
If you want to save a string that will be pointed to by your char pointer- then you ask for allocation in heap for the size of that string- and malloc returns the pointer to that memory allocation on heap.
So, you already have a space for your char array, char pointer, char and int that was allocated when you asked to make a new struct and do not need to allocate it again.
also, keep in mind malloc returns a pointer to the allocated place on the heap- so if you malloc(sizeof(int)) you get a pointer to a memory allocation for an int on the heap- which is pointed to by a int pointer Not an int.
good luck!
Version 1:
struct mydef_s1 {
int argc;
char *argv[3];
};
struct mydef_s1 *p1 = (struct mydef_s1*) malloc (sizeof (struct mydef_s1));
p1->argv[0] = malloc (8);
p1->argv[1] = malloc (16);
p1->argv[2] = malloc (24);
Now, I want to achieve above with the following structure declaration?
Version 2:
struct mydef_s2 {
int argc;
char **argv;
};
If I am right, then following would like allocate just 8 bytes (4 for memory pointer & 4 for integer in my machine)
struct mydef_s2 *p2 = (struct mydef_s2*) malloc (sizeof (struct mydef_s2));
What should I do to do the following?
p2->argv[0]= malloc(4);
p2->argv[1]=malloc(8);
In the case of a pointer to pointer like
struct mydef_s2 {
int argc;
char **argv;
};
you have to first allocate the memory for argv itself, then for argv[i]s.
Something like (code is without error check)
argv = malloc(n * sizeof*argv); //allocate memory to hold 'n' number of 'argv[i]'s
for (i = 0; i < n; i++)
argv[i] = malloc(32); //allocate individual `argv[i]`s
will do the job.
A pointer in C is behaving somewhat like an array. A pointer to pointer, however, is something completely different than a two dimensional array.
If you meant what you typed, i.e. - an array of a non (compiled time) known size of pointers to arrays of non compiled time known sizes of chars, then you will need to do just that. Allocate storage for the array of pointers, place that in your argv, and then initialize each position there with a pointer, possibly dynamically allocated with malloc, of the actual array of chars.
If, on the other hand, you meant a two dimensional array, you have two ways to proceed. One is to do the above, possibly saving a step by allocating the inner nesting in one malloc at one go. This is somewhat wasteful in memory.
The other option is to simulate what the compiler does for two dimensional arrays. Allocate n*m chars as a single dimension array, and jump into it by with the formula i = r*m + c, where r is the row index, m is the row size, and c is the column index.
While somewhat verbose, this is what C does when you define a two dimensional array. It is also quicker to allocate, initialize and use than the alternative.
I'm currently working on dynamically allocating my array of structures and I'm unsure how to continue. This is my structure:
struct Word_setup
{
char word[M];
int count;
} phrase[N];
I know malloc returns a pointer to a block of memory, but I'm not sure how this works when it comes to an array of structures.
If anyone could please clarify that would be much appreciated!
Probably you meant:
struct Word_setup {
char word[M];
int count;
};
It's a good idea to avoid defining variables in the same line as a struct definition anyway, to help with code readability.
Then you can allocate an array of these:
int main()
{
struct Word_setup *phrase = malloc(N * sizeof *phrase);
// use phrases[x] where 0 <= x < N
phrase = realloc(phrase, (N+5) * sizeof *phrase);
// now can go up to phrases[N+4]
free(phrase);
}
Of course you should check for failure and abort the program if malloc or realloc returns NULL.
If you also want to dynamically allocate each string inside the word then there are a few options; the simplest one to understand is to change char word[M] to char *word; and each time you allocate a phrase, write the_phrase.word = malloc(some_number); . If you allocate an array of words you'll need to loop through doing that for each word.
I suppose that N and M is a compile-time known constants. Then just use sizeof, .e.g.
struct Word_setup*ptr = malloc(sizeof(struct Word_setup)*N);
Maybe you want a flexible array member. Then, it should always be the last member of your struct, e.g.
struct Word_setup {
int count;
unsigned size;
char word[]; // of size+1 dimension
};
Of course it is meaningless to have an array of flexibly sized structures -you need an array of pointers to them.
I have declared array of known size,
typedef struct{
......
char * buffer[height+1]; //height is a constant int
......} args;
int main{
args * info;
info = malloc (sizeof(args));
char* output_buffer[width][height+1]; //width is also a constant int >= 4
output_buffer[2] = malloc (sizeof(char)*char_per_line*(height+1)); // error same as below
info->buffer = output_buffer[2]; // I know it's wrong. incompatible types in assignment
....}
Numbers are arbitrary and used just for illustration.
What i am doing is to assign the address of output_buffer[width] to info->buffer, and then pass info as an argument to a thread, which generates data an array of size height+1; in each slot is a cstring of length char_per_line. Those cstrings are stored in output_buffer[2].
I am confused here that isn't the output_buffer[2] a pointer of type char*[height+1]? Then why can't I assign address of memory from malloc to it?
Also, I know that I cannot assign an array to an array, but how can I get the code work in desired way? If the solution is to use a char** as char*[height+1], then how can I access info->buffer[height], say?
Thanks in advance!
According to the requirement you are specifying, this is what you need to do
/* This is a 2D array of pointers. */
char* output_buffer[width][height+1];
for ( int i =0; i< width; i++ )
for ( int j=0; j <height+1; j++ )
output_buffer[i][j] = malloc (sizeof(char)*char_per_line*(height+1));
And then,
info->buffer[SOME_VALUE] = output_buffer[SOME_WIDTH][SOME_HEIGHT];
I am confused here that isn't the output_buffer[2] a pointer of type
char*[height+1]? Then why can't I assign address of memory from malloc
to it?
malloc returns a single dimensional pointer void* but as you have noted, output_buffer[2] is not a single dimensional pointer. It is of type char*[height+1]. [] adds one more dimension apart from the *.
isn't the output_buffer[2] a pointer of type char*[height+1]?
No. output_buffer[2] is an array of size height+1. Its element type is char*.
Then why can't I assign address of memory from malloc to it?
As you know, you cannot assign to an array.
array of size height+1; in each slot is a cstring of length char_per_line.
how can I get the code work in desired way?
If you need an array of (height+1) C strings, each of size char_per_line, you need to allocate (height+1) C strings of size char_per_line. That is, call malloc (height+1) times and pass char_per_line to each. (There's a way to do it in one call to malloc but you probably don't want to do that right now).
typedef struct{
......
char * buffer[height+1]; //height is a constant int
......} args
this has to be
typedef struct{
......
char ** buffer; //height is a constant int
......} args
output_buffer[2] = malloc (sizeof(char)*char_per_line*(height+1));
you have to this in a for loop, and for all output_buffer[i][j], (now it is char ** = char *).
struct integer* convert_integer(char* stringInt)
{
struct integer* convertedInt_1;
char* stringArray3 = (char *) malloc (sizeof(char));;
free(stringArray3);
stringArray3 = stringInt;
convertedInt_1->digits = atoi(stringArray3);
stringArray4 = stringInt;
}
this is a sample of the code. this code is giving me an error when i use the standard library from c "Warning: assignment makes pointer from integer to without a cast"
so i need to know how to convert a dynamically numerical string into dynimacally struct integer
You do not need any dynamic allocation for char string here, nor do you need an additional char * pointer.
struct integer* convert_integer(char* stringInt)
{
/*Allocate memory to structure,You cannot return pointer to local structure*/
struct integer* convertedInt_1 = (struct integer*)malloc(sizeof(*convertedInt_1));
/*Convert the string to integer*/
int i = atoi(stringInt);
/*Assign converted integer to structure member*/
convertedInt_1->digits = i;
/*return pointer to heap allocated structure*/
return convertedInt_1 ;
}
There are a lot of problems with this code, but I'll try to walk you through them.
One, you malloc only one char worth of memory, not the amount of memory needed to hold your array. You really need to include an argument for the size of the array to be changed if the string is not null terminated.
Second, you're trying to use memory after you free it. This is bad. Very bad. You should only free memory after you're finished with it.
Next, you're trying to atoi the entire array at once. This is going to try to change the entire string into one number, not one int.
What I think you want, is to convert each character from stringInt to a (single digit) int in your result. For this, use a for loop to iterate through the array.
I'm pretty sure you want to be using int and not integer.
Last, you forgot to return anything - this doesn't compile.