I am making a struct with undefined size.
#define namemax 128
struct Image{
char name[namemax+1];
int length;
double *array; //double array[256]
};
struct Image* graph;
graph=malloc(max*sizeof(struct Image));
If I define array[256], everything work fine.
but if I use double *array, and then write
graph[check].array = malloc( 100 * sizeof(double *));
it creates a segment fault.
I was wondering how can I define the size using malloc and realloc for array.
If I add value in the array, it shows segment fault.
struct Image* graph;//outside the while loop
while: //it is inside the while loop
//basically it read different name each line, and put the x and y to the array
graph[check].array = malloc( 100 * sizeof(double));
check++;
strcpy( graph[check].name,type);
graph[check].array[count]=shiftX;
graph[check].array[count+1]=shiftY;
That because double * array is declaring a pointer to an array, not storage. You want to declare storage here. The easiest way is to simply define the array as double array[1] and make sure it's the last element in the struct. You can then allocate space for the structure using malloc() and realloc() by passing them the size of the base struct plus the size of the array (sizeof double * the number of array elements).
One problem I see is using sizeof(double *) instead of sizeof(double) even if both are the same if you're using x86-64 architecture.
i think it makes seg fault because in malloc you have said sizeof(double *) (Actually you declare an array of array).
Just try to say sizeof(double) it may work but I dont know that for sure because I haven't tested it.
And by the way when you declare array staticly you reserve space for it when you declare your struct variable but when you declare it as pointer ( dynamic array ) you should reserve space for it and you can change the array's size. You should use realloc google it.
I don't know what is the correct way to allocate memory dynamically:
I have a .csv file which has like 50 lines and I need to allocate enough space in memory to save each line of the file in one space of the struct vector.
Also, I know that the return of malloc is the first position of the allocated memory space.
Example:
typedef struct{
int a;
float b;
char name[10]; //This will be set dynamically too, later...
}my_struct;
int main(){
int *p_array;
size_t vector_size = 2; //Same as doing: my_struct struc[2] ?
p_array = (int *) malloc(vector_size * (int));
my_struct struc[p_array];
return 0;
}
Is it right? If not which is the right way of doing it. I got no errors, but I don't know why it doesn't seems right.
It's completely wrong, starting here
This is wrong
p_array = (int *) malloc(vector_size * (int));
/* ^ what is this? */
if you want an array of integers of vector_size size you need
p_array = malloc(vector_size * sizeof(int));
/* ^ the sizeof operator */
This doesn't make sense at all
my_struct struc[p_array];
maybe you mean?
my_struct struc[vector_size];
above you are passing a pointer where an integer should go, if this compiles then what is happening is that the address stored in the pointer is evaluated as an integer and hence your struc array has a size very different than what you think
If you use the corrected version of this, the malloc() makes absolutely no sense, so you don't really need it.
If you want to allocate the struc array dynamically then
my_struct *array;
array = malloc(elementCount * sizeof(my_struct)):
if (array == NULL)
pleaseDoNot_Use_array_AndProbably_AbortHere();
/* you can use it here, and when you finish */
free(array);
If you enable compiler warnings there will be a few warnings that will let you know some of the things I mentioned above.
Also, in c There is no need to cast malloc()
I've allocated an "array" of mystruct of size n like this:
if (NULL == (p = calloc(sizeof(struct mystruct) * n,1))) {
/* handle error */
}
Later on, I only have access to p, and no longer have n. Is there a way to determine the length of the array given just the pointer p?
I figure it must be possible, since free(p) does just that. I know malloc() keeps track of how much memory it has allocated, and that's why it knows the length; perhaps there is a way to query for this information? Something like...
int length = askMallocLibraryHowMuchMemoryWasAlloced(p) / sizeof(mystruct)
I know I should just rework the code so that I know n, but I'd rather not if possible. Any ideas?
No, there is no way to get this information without depending strongly on the implementation details of malloc. In particular, malloc may allocate more bytes than you request (e.g. for efficiency in a particular memory architecture). It would be much better to redesign your code so that you keep track of n explicitly. The alternative is at least as much redesign and a much more dangerous approach (given that it's non-standard, abuses the semantics of pointers, and will be a maintenance nightmare for those that come after you): store the lengthn at the malloc'd address, followed by the array. Allocation would then be:
void *p = calloc(sizeof(struct mystruct) * n + sizeof(unsigned long int),1));
*((unsigned long int*)p) = n;
n is now stored at *((unsigned long int*)p) and the start of your array is now
void *arr = p+sizeof(unsigned long int);
Edit: Just to play devil's advocate... I know that these "solutions" all require redesigns, but let's play it out.
Of course, the solution presented above is just a hacky implementation of a (well-packed) struct. You might as well define:
typedef struct {
unsigned int n;
void *arr;
} arrInfo;
and pass around arrInfos rather than raw pointers.
Now we're cooking. But as long as you're redesigning, why stop here? What you really want is an abstract data type (ADT). Any introductory text for an algorithms and data structures class would do it. An ADT defines the public interface of a data type but hides the implementation of that data type. Thus, publicly an ADT for an array might look like
typedef void* arrayInfo;
(arrayInfo)newArrayInfo(unsignd int n, unsigned int itemSize);
(void)deleteArrayInfo(arrayInfo);
(unsigned int)arrayLength(arrayInfo);
(void*)arrayPtr(arrayInfo);
...
In other words, an ADT is a form of data and behavior encapsulation... in other words, it's about as close as you can get to Object-Oriented Programming using straight C. Unless you're stuck on a platform that doesn't have a C++ compiler, you might as well go whole hog and just use an STL std::vector.
There, we've taken a simple question about C and ended up at C++. God help us all.
keep track of the array size yourself; free uses the malloc chain to free the block that was allocated, which does not necessarily have the same size as the array you requested
Just to confirm the previous answers: There is no way to know, just by studying a pointer, how much memory was allocated by a malloc which returned this pointer.
What if it worked?
One example of why this is not possible. Let's imagine the code with an hypothetic function called get_size(void *) which returns the memory allocated for a pointer:
typedef struct MyStructTag
{ /* etc. */ } MyStruct ;
void doSomething(MyStruct * p)
{
/* well... extract the memory allocated? */
size_t i = get_size(p) ;
initializeMyStructArray(p, i) ;
}
void doSomethingElse()
{
MyStruct * s = malloc(sizeof(MyStruct) * 10) ; /* Allocate 10 items */
doSomething(s) ;
}
Why even if it worked, it would not work anyway?
But the problem of this approach is that, in C, you can play with pointer arithmetics. Let's rewrite doSomethingElse():
void doSomethingElse()
{
MyStruct * s = malloc(sizeof(MyStruct) * 10) ; /* Allocate 10 items */
MyStruct * s2 = s + 5 ; /* s2 points to the 5th item */
doSomething(s2) ; /* Oops */
}
How get_size is supposed to work, as you sent the function a valid pointer, but not the one returned by malloc. And even if get_size went through all the trouble to find the size (i.e. in an inefficient way), it would return, in this case, a value that would be wrong in your context.
Conclusion
There are always ways to avoid this problem, and in C, you can always write your own allocator, but again, it is perhaps too much trouble when all you need is to remember how much memory was allocated.
Some compilers provide msize() or similar functions (_msize() etc), that let you do exactly that
May I recommend a terrible way to do it?
Allocate all your arrays as follows:
void *blockOfMem = malloc(sizeof(mystruct)*n + sizeof(int));
((int *)blockofMem)[0] = n;
mystruct *structs = (mystruct *)(((int *)blockOfMem) + 1);
Then you can always cast your arrays to int * and access the -1st element.
Be sure to free that pointer, and not the array pointer itself!
Also, this will likely cause terrible bugs that will leave you tearing your hair out. Maybe you can wrap the alloc funcs in API calls or something.
malloc will return a block of memory at least as big as you requested, but possibly bigger. So even if you could query the block size, this would not reliably give you your array size. So you'll just have to modify your code to keep track of it yourself.
For an array of pointers you can use a NULL-terminated array. The length can then determinate like it is done with strings. In your example you can maybe use an structure attribute to mark then end. Of course that depends if there is a member that cannot be NULL. So lets say you have an attribute name, that needs to be set for every struct in your array you can then query the size by:
int size;
struct mystruct *cur;
for (cur = myarray; cur->name != NULL; cur++)
;
size = cur - myarray;
Btw it should be calloc(n, sizeof(struct mystruct)) in your example.
Other have discussed the limits of plain c pointers and the stdlib.h implementations of malloc(). Some implementations provide extensions which return the allocated block size which may be larger than the requested size.
If you must have this behavior you can use or write a specialized memory allocator. This simplest thing to do would be implementing a wrapper around the stdlib.h functions. Some thing like:
void* my_malloc(size_t s); /* Calls malloc(s), and if successful stores
(p,s) in a list of handled blocks */
void my_free(void* p); /* Removes list entry and calls free(p) */
size_t my_block_size(void* p); /* Looks up p, and returns the stored size */
...
really your question is - "can I find out the size of a malloc'd (or calloc'd) data block". And as others have said: no, not in a standard way.
However there are custom malloc implementations that do it - for example http://dmalloc.com/
I'm not aware of a way, but I would imagine it would deal with mucking around in malloc's internals which is generally a very, very bad idea.
Why is it that you can't store the size of memory you allocated?
EDIT: If you know that you should rework the code so you know n, well, do it. Yes it might be quick and easy to try to poll malloc but knowing n for sure would minimize confusion and strengthen the design.
One of the reasons that you can't ask the malloc library how big a block is, is that the allocator will usually round up the size of your request to meet some minimum granularity requirement (for example, 16 bytes). So if you ask for 5 bytes, you'll get a block of size 16 back. If you were to take 16 and divide by 5, you would get three elements when you really only allocated one. It would take extra space for the malloc library to keep track of how many bytes you asked for in the first place, so it's best for you to keep track of that yourself.
This is a test of my sort routine. It sets up 7 variables to hold float values, then assigns them to an array, which is used to find the max value.
The magic is in the call to myMax:
float mmax = myMax((float *)&arr,(int) sizeof(arr)/sizeof(arr[0]));
And that was magical, wasn't it?
myMax expects a float array pointer (float *) so I use &arr to get the address of the array, and cast it as a float pointer.
myMax also expects the number of elements in the array as an int. I get that value by using sizeof() to give me byte sizes of the array and the first element of the array, then divide the total bytes by the number of bytes in each element. (we should not guess or hard code the size of an int because it's 2 bytes on some system and 4 on some like my OS X Mac, and could be something else on others).
NOTE:All this is important when your data may have a varying number of samples.
Here's the test code:
#include <stdio.h>
float a, b, c, d, e, f, g;
float myMax(float *apa,int soa){
int i;
float max = apa[0];
for(i=0; i< soa; i++){
if (apa[i]>max){max=apa[i];}
printf("on i=%d val is %0.2f max is %0.2f, soa=%d\n",i,apa[i],max,soa);
}
return max;
}
int main(void)
{
a = 2.0;
b = 1.0;
c = 4.0;
d = 3.0;
e = 7.0;
f = 9.0;
g = 5.0;
float arr[] = {a,b,c,d,e,f,g};
float mmax = myMax((float *)&arr,(int) sizeof(arr)/sizeof(arr[0]));
printf("mmax = %0.2f\n",mmax);
return 0;
}
In uClibc, there is a MALLOC_SIZE macro in malloc.h:
/* The size of a malloc allocation is stored in a size_t word
MALLOC_HEADER_SIZE bytes prior to the start address of the allocation:
+--------+---------+-------------------+
| SIZE |(unused) | allocation ... |
+--------+---------+-------------------+
^ BASE ^ ADDR
^ ADDR - MALLOC_HEADER_SIZE
*/
/* The amount of extra space used by the malloc header. */
#define MALLOC_HEADER_SIZE \
(MALLOC_ALIGNMENT < sizeof (size_t) \
? sizeof (size_t) \
: MALLOC_ALIGNMENT)
/* Set up the malloc header, and return the user address of a malloc block. */
#define MALLOC_SETUP(base, size) \
(MALLOC_SET_SIZE (base, size), (void *)((char *)base + MALLOC_HEADER_SIZE))
/* Set the size of a malloc allocation, given the base address. */
#define MALLOC_SET_SIZE(base, size) (*(size_t *)(base) = (size))
/* Return base-address of a malloc allocation, given the user address. */
#define MALLOC_BASE(addr) ((void *)((char *)addr - MALLOC_HEADER_SIZE))
/* Return the size of a malloc allocation, given the user address. */
#define MALLOC_SIZE(addr) (*(size_t *)MALLOC_BASE(addr))
malloc() stores metadata regarding space allocation before 8 bytes from space actually allocated. This could be used to determine space of buffer. And on my x86-64 this always return multiple of 16. So if allocated space is multiple of 16 (which is in most cases) then this could be used:
Code
#include <stdio.h>
#include <malloc.h>
int size_of_buff(void *buff) {
return ( *( ( int * ) buff - 2 ) - 17 ); // 32 bit system: ( *( ( int * ) buff - 1 ) - 17 )
}
void main() {
char *buff = malloc(1024);
printf("Size of Buffer: %d\n", size_of_buff(buff));
}
Output
Size of Buffer: 1024
This is my approach:
#include <stdio.h>
#include <stdlib.h>
typedef struct _int_array
{
int *number;
int size;
} int_array;
int int_array_append(int_array *a, int n)
{
static char c = 0;
if(!c)
{
a->number = NULL;
a->size = 0;
c++;
}
int *more_numbers = NULL;
a->size++;
more_numbers = (int *)realloc(a->number, a->size * sizeof(int));
if(more_numbers != NULL)
{
a->number = more_numbers;
a->number[a->size - 1] = n;
}
else
{
free(a->number);
printf("Error (re)allocating memory.\n");
return 1;
}
return 0;
}
int main()
{
int_array a;
int_array_append(&a, 10);
int_array_append(&a, 20);
int_array_append(&a, 30);
int_array_append(&a, 40);
int i;
for(i = 0; i < a.size; i++)
printf("%d\n", a.number[i]);
printf("\nLen: %d\nSize: %d\n", a.size, a.size * sizeof(int));
free(a.number);
return 0;
}
Output:
10
20
30
40
Len: 4
Size: 16
If your compiler supports VLA (variable length array), you can embed the array length into the pointer type.
int n = 10;
int (*p)[n] = malloc(n * sizeof(int));
n = 3;
printf("%d\n", sizeof(*p)/sizeof(**p));
The output is 10.
You could also choose to embed the information into the allocated memory yourself with a structure including a flexible array member.
struct myarray {
int n;
struct mystruct a[];
};
struct myarray *ma =
malloc(sizeof(*ma) + n * sizeof(struct mystruct));
ma->n = n;
struct mystruct *p = ma->a;
Then to recover the size, you would subtract the offset of the flexible member.
int get_size (struct mystruct *p) {
struct myarray *ma;
char *x = (char *)p;
ma = (void *)(x - offsetof(struct myarray, a));
return ma->n;
}
The problem with trying to peek into heap structures is that the layout might change from platform to platform or from release to release, and so the information may not be reliably obtainable.
Even if you knew exactly how to peek into the meta information maintained by your allocator, the information stored there may have nothing to do with the size of the array. The allocator simply returned memory that could be used to fit the requested size, but the actual size of the memory may be larger (perhaps even much larger) than the requested amount.
The only reliable way to know the information is to find a way to track it yourself.
I'm pretty new to c, so if my steps are wrong, please let me know. Let's say that I have something like the following:
struct graphNode{
int val;
graphNode* parent;
int succSize;
int succMaxSize;
graphNode* succ[1];
};
I will create a new node with:
graphNode *n;
n = malloc(sizeof(struct graphNode));
assert(n);
n->val = 1;
n->parent = NULL;
n->succSize = 0;
n->succMaxSize = 1;
Then, if I want to add a successor to the node
if (n->succSize == n->succMaxSize){
n->succ = realloc(n->succ, sizeof(graphNode*) * n->succMaxSize * 2);
n->succMaxSize *= 2;
}
n->succ[succSize] = n2; //n2 is of type graphNode*
succSize++;
Is this correct? Do I need to realloc for the struct as well or is realloc of the array enough? Do I need to malloc for the initial array? Should the initial array size be included in my malloc call for n?
The usual way to define a "stretchy" array member in C is to either specify a size of 0 or no size at all, e.g.:
struct foo {
int stuff;
bar theBars[]; // or theBars[0]
};
With this definition, sizeof(struct foo) will include all the elements other than the array at the end, and you can allocate the right size by saying malloc(sizeof(struct foo) + numberOfBars * sizeof(bar)).
If you need to reallocate it to change the number of bar elements, then you'll use the same formula (but with a new numberOfBars).
To be clear, you can't just realloc part of a struct. You have to realloc the whole thing.
realloc(ptr,size) needs 2 parameters, not 1 as used in realloc(sizeof(graphNode*) * n->succMaxSize * 2)
// Something like ...
graphNode *n;
n->succSize = 0;
n->succMaxSize = 0; // set to 0
n->succ = NULL; // Initialize to NULL
// Then, if OP wants to add a successor to the node
if (n->succSize <= n->succMaxSize){
n->succ = realloc(n->succ, sizeof(graphNode*) * n->succMaxSize * 2);
n->succMaxSize *= 2;
}
n->succ[succSize++] = n2;
As with all memory allocations, check for NULL return. In realloc(), one should save the original value, so if the realloc() fails, the original pointer is not lost.
Usually when you see struct definition where the last field is an array of size 0 or 1 it means the author is going to do some subtle stuff with malloc when the struct is malloced.
For example
struct foo {
int x;
:
:
type a[0];
};
With a malloc like
struct foo *p = malloc(sizeof(*p) + (n * sizeof(type));
What this does is it allocates a contiguous chunk of memory for the struct and the trailing array. In this case the array size is n. So references to the array in this case are:
p->a[i] // where i >= 0 and i < n
One reason for doing this is to save memory.
I'm sure there are better explanations for this on StackOver; it's a very common C idiom.
It's generally not used when the array is dynamic. Rather, it is used when the array size is known at malloc() time. You can use dynamically, of course, but you have to realloc the entire memory chunk, not just the struct or array by itself. To increase the size to 2n you would say
p = realloc(p, sizeof(*p) + (2 * n * sizeof(type)));
Now your array is twice is big as it was, and it's still one chunk of memory.
If you only want a single array, just make succ a single pointer and only use malloc/realloc etc. to allocate memory for the array.
graphNode* succ;
What you are doing is almost certain to break.
I too am new to C, but there's some things that I can see right off the bat. First of all, you can't re-allocate arrays. In c89, they're compile-time fixed-size. In C99 and C11, they can be dynamically allocated, but not reallocated (as far as I'm aware). So for this, you need to allocate a
graphnode *succ;
pointer, and malloc(nodes * sizeof(node)).
graphNode* succ[1];
This creates an array of size one, not an array with a maximum index of one. So, it is the same (almost) functionally as
graphNode* succ;
except that you can't change its size once you've made it.
I think what you want is to make a tree, with a dynamically re-allocable amount of branches. In this case, you only need to reallocate the size of the graphNode* pointer, and then access each element via index as you would an array.
I made a structure like so:
struct ponto {
int x;
int y;
int z;
};
1) Can I initialize the int's with a default value? int var = value; doesn't seem to work, compiler says "syntax error before '=' token" or something of sorts.
2) I need to work with several of these like in a array of structures, but I only know how many I need after the application starts up, after reading a file. How can I malloc this?
Thanks in advance
EDIT: So many answers, I'm grateful. Sadly I can only mark one
a) You can initalise with
struct pronto p = {1,2,3};
In recent compilers (not sure how portable this is, think it's C99?)
b) You can allocate an array with malloc:
struct pronto *array = malloc(sizeof(struct pronto) * NUMBER);
To initialize your structure members to 0, do:
struct ponto foo = { 0 };
To malloc() an array of the right size, do:
struct ponto *arr = (struct ponto *) malloc(COUNT * sizeof(struct ponto));
Don't forget to free() the array when you're done with it.
struct ponto* create_and_init_ponto(int n)
{
struct ponto* array;
int i;
array = (struct ponto*)malloc( n * sizeof(struct ponto) );
for ( i = 0; i < n; ++i )
{
array[ i ].x = 0;
array[ i ].y = 0;
array[ i ].z = 0;
}
return array;
}
You'e made a structure definition, now you have to create a variable of that structure before you can set the fields:
struct ponto xyz;
xyz.x = 7;
To allocate enough space:
int need_to_have = 24;
struct ponto *pontos = malloc (need_to_have * sizeof(struct ponto));
You cannot have "default" values for structure members. Space is not allocated for a structure definition. You're just creating a new type (like the inbuilt int). When you actually define a variable of type ponto, space will be allocated to it.
You can make an educated guess about how many you will need, allocate space for that many (using malloc) and go ahead. If you find that you're reaching the limit, you can use the realloc function to resize your array.
1) You cannot give a specific structure default values for its elements at the language level, because all variables in C are uninitialized unless you explicitly initialize them (or make them static/external in which case they're zero-initialized). If you design your structs such that all-zeros is a good set of initial values, though, you can always initialize like this:
struct foo myfoo = {0};
The {0} serves as a universal zero-initializer which works for any type.
If you need different defaults, the best way is to use a macro and document that code using your structure must use the macro:
#define FOO_INITIALIZER { 1, 2, 3 }
struct foo myfoo = FOO_INITIALIZER;
2) If you know before you start using any of the struct how many you will need, simply malloc them all once you know the number:
if (count > SIZE_MAX / sizeof *bar) abort();
struct foo *bar = malloc(count * sizeof *bar);
Note the proper idiom for calling malloc and avoiding overflow vulnerabilities.
If you don't know the number you'll need until you start working with them, start out by allocating a decent number, and if you run out, increase the number by a fixed multiple, for example doubling the size is common and easy. You'll want to check for overflows here. Then use realloc.
Question #1: If you need to initialize int with a value:
struct ponto p1;
p1.x = p1.y = p1.z = 3; // initializing with three
Alternatively, if you want to initialize all values to 0, you can use memset like this:
memset(&p1, 0, sizeof(struct ponto));
Question #2: To use malloc:
struct ponto *ps;
ps = (struct ponto *)malloc(N*sizeof(struct ponto));
// where N is your element count.
This will allocate memory to store N elements of type struct ponto. After that, you can initialize its values with:
int initvalue = 3; // assuming you want to initialize points with value 3
for (i=0; i<N; i++) {
ps[i].x = ps[i].y = ps[i].z = initvalue;
}