Pointer to struct containing array - c

I have a simple struct containing an array of ints and an index to be used for that array.
#define BUFF_SIZE 100
typedef struct _buffer Buffer;
struct _buffer {
int buff[BUFF_SIZE];
int index;
};
I am trying to write a function to create a pointer to an instance of this struct, and initialise its values to zero. However when I try to initialise the array using the arrow operator I get an error that the expression is invalid.
...
Buffer* newBuff;
newBuff->buff = {0}; //Error occurs here
...
I know that in c an array is a pointer to the base of the memory block in which the array resides, but was under the impression that dereferencing the struct pointer would allow me to access the array. Am I wrong about this, or am I missing something here? I have a feeling that it is something very simple, but for the life of me I just can't spot it.
Thanks!
EDIT: Thanks for the quick answers guys, they've helped me understand some of what is occurring. I neglected to mention that this is intended to be run on an embedded system (sorry about that), so I would like to avoid using includes or malloc if at all possible.

There are several types of confusion here. A pointer points to memory (duh), but you need to get that memory from somewhere. How you initialize that memory is separate.
You can allocate your structure on the stack by declaring a local variable inside your function:
// Initialize all buff elements and index to 0
// Note: Buffer, not Buffer*
Buffer newBuf = { {0}, 0 };
Or you can allocate it on the heap:
Buffer *newBuf = malloc(sizeof(Buffer));
memset(newBuf, 0, sizeof(Buffer));
When allocating objects on the stack, they are only valid while the current function is executing. You can't return a pointer to an object on the stack. Further, stack space is typically limited, so you can't put megabyte-sized objects there. When allocating memory on the heap with malloc(), you need to take care to free() when it is not used any more, otherwise you leak memory.
You see that when allocating objects on the stack, you are able to use an initializer-list { {0}, 0 }. In the heap case, you can not do that and you have to zero the memory manually using memset.

The problem is not with the arrow -> operator, it's with the right side of the assignment: {0} is allowed in initializers, but you cannot assign an array like that. You need to use memset to zero out the elements of the array:
memset(newBuff->buff, 0, sizeof(newBuff->buff));
Note: your code does not set the newBuf to a valid location in memory. You need to allocate memory first, like this:
newBuff->buff = malloc(sizeof(*newBuff));

I have to disagree with #dasblinkenlight, but I think the problem is that newBuff is a pointer, but it hasn't been given a value. Hence, when you dereference it, you'll probably get a crash or unpredictable results.
You'd have to have a statement that's something like:
newBuff = malloc(sizeof (Buffer));
to allocate space of the appropriate size and assign it to newBuff.
Unless I'm missing something terribly obvious...

From your question I was able to understand- you want to initialize all array elements of structure variable buff[ ] to zero.
memset() function from <string.h> file will help you to solve this problem.
As you said you are writing code for embedded system so there is no need to include whole <string.h> file in your program
I tried to replicate your program and found the following solution-
void *memset(void * , int , size_t ) __attribute__((__nonnull__(1)));
#define BUFF_SIZE 100
typedef struct _buffer Buffer;
struct _buffer {
int buff[BUFF_SIZE];
int index;
};
int main (void)
{
Buffer* newBuff;
memset(newBuff->buff, 0, BUFF_SIZE);
}
Please let me know if it was helpful.

Related

How do I define a struct and properly allocate memory for it in C?

I've recently started learning C and currently I'm working on a project which involves implementing a struct with two variables and I don't really know how to apparoach this.
The gist of it is I need to implement a struct which contains two variables, a pointer to an int array AND an int value which indicates the number of elements conatained within the array. The size of the array is declared upon the invocation of the constructor and is dependent on the input.
For the constructor I'm using a different function which recieves a string
as input which is encoded into a decimal code. Also this function recieves another input
which is a pointer to an int array (the pointer defined in the struct) and the problem is I'm using the malloc() function to allocate memory for it but I dont really understand how and when to use the free() function properly.
So, the questions are:
When am I supposed to free the allocated memory? (assuming I need this struct for later use throughout the program's running time)
What are the best ways to avoid memory leaks? What should you look out for?
It's unclear whether you're expected to manage the memory of the array inside, but this is functionally the setup you need for allocating the containing structure.
#include <malloc.h>
#include <stdio.h>
struct my_struct {
size_t num_entries;
int *array;
};
int main() {
struct my_struct *storage = malloc(sizeof(struct my_struct));
storage->num_entries = 4;
storage->array = malloc(sizeof(int) * storage->num_entries);
storage->array[0] = 1;
storage->array[3] = 2;
printf("allocated %ld entries\n", storage->num_entries);
printf("entry #4 (index=3): %d\n", storage->array[3]);
free(storage->array); /* MUST be first! */
free(storage);
storage = 0; /* safety to ensure you can't read the freed memory later */
}
if you're responsible for freeing the internal storage array, then you must free it first before freeing the containing memory.
The biggest key to memory management: only one part of the code at any time "owns" the memory in the pointer and is responsible for freeing it or passing it to something else that will.

Callocing memory

I'm trying to create a file system and I need to calloc the file descriptors.
Let's say I have two structures with the following definitions:
#define DESCRIPTOR_MAX (256)
#define TABLE_MAX (32)
typedef struct S16FS S16FS_t;
typedef struct {
bitmap_t *fd_status;
size_t fd_pos[DESCRIPTOR_MAX];
inode_ptr_t fd_inode[DESCRIPTOR_MAX];
} fd_table_t;
struct FS {
back_store_t *bs;
fd_table_t fd_table;
};
I'm callocing a new file system with no problem:
FS_t *fs = (FS_t *)calloc(8, sizeof(FS_t));
but my problem arrises when I want to calloc the fd_table within the FS struct. Here's what I'm trying.
This one produces no errors:
fs->fd_table = *(fd_table_t*)calloc(TABLE_MAX, sizeof(fd_table_t));
I'm getting an error with the following:
fs->fd_table.fd_pos = (size_t *)calloc(TABLE_MAX, sizeof(size_t));
error: array type 'size_t [256]' is not assignable
Can someone explain to me what i'm doing wrong or if I'm just completely wrong in my process? Do I even need to calloc the fd_pos?
It looks like fs->fd_table.fd_pos is an array, not a pointer. If you want a dynamic array, then change the type to size_t*.
Otherwise, it's perfectly fine to leave it as an array and not use dynamic allocation. In that case, if you want to zero the memory (as calloc does), you can just use memset:
memset( fs->fd_table.fd_pos, 0, sizeof(fs->fd_table.fd_pos) );
Oh yes, and also WhozCraig points out that your first example is a leak (allocating memory, then dereferencing and copying, followed by losing the pointer). In fact, you don't need to memset as I suggested above because the entire structure was zeroed with the first calloc.

Potential issues with p* in structs?

I have been churning through C for the last several months. In an effort to learn the language, the project is an arithmetic parser - formulas, variables, etc.
I recently decided to go ahead and work out garbage collection because I have a lot of calls to this method:
char* read_token(const Source* source, const Token* token) {
int szWord = token->t_L + 1; // +1 for NULL terminator
char* word = (char*)malloc(sizeof(char)*szWord);
memset(word, '\0', sizeof(char)*(szWord));
char* p_T = source->p_Src + token->t_S;
memcpy(word, p_T, token->t_L);
return word;
}
... which means calling free(...) quite a bit.
The Source struct has two buffer properties among others:
typedef struct source Source;
struct source {
// ...
char* p_Src; // malloc'd source buffer
int srcLen;
Token* p_tokens; // malloc'd Token buffer
// ...
};
The Token struct has start and length properties:
typedef struct token Token;
struct token {
int t_S; // buffer start index
int t_L; // token length
};
In addition, since there could be many sources, a Source* buffer is malloc'd.
When a buffer is malloc'd, the size of the struct is provided (* numStructs). But if a given struct has a buffer that may be allocated at a later time, such as Token*, does that change the size of Source? Is the code in danger of overwriting previously allocated memory?
For some reason I was getting the idea that all of the memory used for a struct, including any buffers, is allocated in a linear manner. If Token* buffer in struct is allocated to 10 tokens, that space is not then linearly allocated within the Source struct right?
The pointer members in your struct are variables that store addresses of memory blocks and as you state yourself pointers and pointees are allocated independently. Hence those buffers might be located just next to where their 'parent' struct is stored, or not (and most probably won't).
If it is needed, ensuring contiguous storage of the struct members and its pointed buffers can be achieved by allocating everything in one call to the *alloc function.
This can be done
using fixed-size buffers: not really convenient since any flexibility on the buffer sizes is lost. Also note that declaring this updates the value of sizeof(struct foo) accordingly.
using C99's flexible array member or tricks to enable the feature in pre-C99 C: Allocate Pointer and pointee at once .
using not recommended hacks resorting on pointer arithmetic, watching out for the compiler's alignment policy.
A pointer in a struct is a fixed size, regardless of what it is pointing at, even if it is uninitialised. That way, sizeof(struct token) is a fixed length.
When malloc is used, the memory is taken somewhere from the heap, we know not where, and should not care either. It is highly unlikely that memory will be allocated anywhere near the original struct, and even if it was, that would be implementation specific and you could not count on that behaviour.
Obviously (?) you should call free() on the pointer before the struct that it lives in is destroyed.
Also note C99's Variable Length Arrays (VLAs).
Sorry, i'm writing this in the "Answer" section instead of "Comments" section because my Stackoverflow reputation isn't high enough yet.
What i was about to comment is Why don't you just use this line:
char word[ sizeof(char)*szWord ];
instead of
char* word = (char*)malloc(sizeof(char)*szWord); ?

calloc, malloc and dynamic struct allocation

I am trying to dynamically allocate an array of structures in c so that I can refer to them the same as if I had done a static declaration. I understand that calloc() does the additional step of initializing all the allocated memory to 0. But, other than that, are the 2 completely interchangeable for the following code? If I am using fread() and fwrite() to get these data structures in and out of a file, does calloc() help or hinder this?
#define MAGIC 13
struct s_myStruct {
int a[6000][400];
int b[6000][400];
int c[6000][400];
};
struct s_myStruct stuff[MAGIC];
vs
struct s_myStruct *stuff = calloc(MAGIC, sizeof(s_myStruct);
Thank you.
They're not the same. Declaring the data like this:
struct s_myStruct stuff[MAGIC];
will leave the memory uninitialized if you're declaring it in function scope (which you must be, given the second choice). Adding = {0} before the semicolon rectifies this.
The second choice, of using calloc, allocates the memory on the heap.
There's always a difference though: sizeof(stuff) will be 13 * sizeof(struct s_myStruct) in the first case, and the size of a pointer in the second case.
You really don't want to do the first one, as you'd be putting 13 * 3 * 6000 * 400 * 4 = 370MB on the stack.
But this has nothing to do with using fread and fwrite.

how to calculate size of pointer pointed memory?

In one function I have written:
char *ab;
ab=malloc(10);
Then in another function I want to know the size of memory pointed by the ab pointer.
Is there any way that I can know that ab is pointing to 10 chars of memory?
No, you don't have a standard way to do this. You have to pass the size of the pointed-to memory along with the pointer, it's a common solution.
I.e. instead of
void f(char* x)
{
//...
}
use
void f(char *x, size_t length)
{
//....
}
and in your code
char *ab = malloc( 10 );
f( ab, 10 );
It's a deep secret that only free() knows for sure. It's likely in your system, but in a totally implementation dependent manner.
A bit awkward, but if you want to keep everything together:
typedef struct
{ // size of data followed by data (C only trick! NOT for C++)
int dimension; // number of data elements
int data[1]; // variable number of data elements
} malloc_int_t;
malloc_int_t *ab;
int dimension = 10;
ab = malloc( sizeof(*ab) + (dimension-1)*sizeof(int) );
ab->dimension = dimension;
ab->data[n] // data access
I've changed the data type to int to make the code a more generic template.
You can't (portably anyway). You have to keep track of the size yourself.
Some implementations of malloc could give you an API to access that information, but there is no provisions in the standard for this.
The size is what you passed into malloc, you can use a global variable or macro to remember it.
There is no way, you have to store the size of the allocated memory in another variable.
No, unfortunately.
You need to pass the size of the block along with the pointer.
No.
Now, that being said, there are non-portable hacks to do this, but it is not safe to rely upon them.
If you know with 100% certainty that the memory was allocated via malloc(), you may be able to rewind the pointer a few bytes and inspect the 'malloc node' that is used to track which parts of memory have been allocated and which have not. However, I can not stress this enough--do not ever depend upon this.
There is no way to deduce the size of allocated memory from the pointer itself. Since ab is a char *, sizeof(ab) is the same as sizeof(char *), which obviously is not the same as the size of the allocated chunk of memory.
Since you called malloc with the required size, you know what the size is. Pass this number along with the pointer to the function that needs to know the size.
I had a structure and a char pointer pointing to its memory address. So relating it to your question, I wanted to find the size of the memory location it was pointing to i.e. the size of the structure. So logically what you do is, find the size of the object the pointer creates to. This worked for me:
unsigned char * buffer= Library1Structure;
int x=sizeof(Library1Structure);
So the value of x tells me the size of the memory location the pointer buffer points to.

Resources