I seem to be having some issues with malloc in my code. Here's what's going on.
I've got a struct created with a few values in it. From there, I'd like to make an array of structs. I think I've got the struct right, and some of the pointers, but I'm not sure.
Here's the struct:
typedef struct{
char name[25];
int courseID;
} course;
From there, I try to initiate the new struct and malloc it at the same time by this:
course *courses = malloc(25*sizeof(course));
From here, I'm getting the error:
Invalid conversion from 'void*' to 'course*' [-fpermissive] course
*courses = malloc(25*sizeof(course));
I don't really know what this means... I know I may be completely off course with this whole idea, so any help y'all can give would be great!
You must be using a C++ compiler. You want to compile with a C compiler.
Make sure your file name ends in .c not .cpp or .cc.
You also said you try to initialize (you said initiate but I am translating) the new struct. Malloc will not do that. Malloc allocated memory will contain random values left over from the last user of that memory. The calloc function might work better for what you want since it sets the memory to zero after allocating it.
You are initializing memory with malloc, which returns a void pointer to the allocated memory. You are then assigning this pointer to a course pointer. So there is a pointer mismatch and hence the warning. To bypass it use
course *courses = (course *)malloc(25 * sizeof(course))
Related
So i wrote the following code.
NameOfStruct *S;
if (statement) {
S = (S)->property[10];
}
I defined the structure beforehand. So the error i am getting is this:
'*S' is a pointer; did you mean to use '->'? and then the line where i typed the code. I find this weird since they ask me if i meant -> while that is exactly what i use. If i instead use the following code
S = (*S)->property[10]
then i get that that there is a wrong assignment with an incompatible pointer type.
What is happening here?
Your question is kind of hard to understand, but I think I understood enough to help you.
I think your problem might be in the way you defined the struct, and not on the code that uses it.
Firstly, I don't know what NameOfStructis, so i'll define one in this example:
typedef struct test {
int someValue;
char someString[10];
}EXAMPLE;
What this does is define a struct. You can either call for struct test or EXAMPLE when you want to do something with that struct.
Now, when it comes to use that struct, you can only use -> when you are dealing with pointers. Also, when using Structs, you should allocate memory using malloc().
In your main, you should have something like this:
int main () {
//Declare pointer to struct and allocate memory.
EXAMPLE *test = (EXAMPLE*) malloc(sizeof(EXAMPLE));
//Manipulate data on struct
test->someValue = 10;
test->someString = "Testing";
free(test);
}
This way, you should be left with a struct where on someValue the content is 10and on someString the content is Testing
Also, if in your main you don't feel like using EXAMPLE you can also just use struct test. Don't forget to free the memory you allocated when you don't need it anymore.
PS: Please, next time you ask a question be sure to give a good explanation on what the problem is, show us what your attempt was, and give us the input/output you were expecting paired with the input/output that you got. If you're left with any questions, feel free to reply to this answer and I'll try to help you
I created a struct like the following:
typedef struct header{
int hc;
char src[18];
char dst=[18];
char reason[15];
char d[3];
char m[3];
char y[4];
struct measurements{
char h_ip[17];
int h_ttl;
int h_id;
float h_rtt;
}HOPS[100];
}HEADER;
INSIDE MAIN:
HEADER *head;
for(...){
head=(HEADER*) malloc(sizeof(HEADER));
.....
free(head);
}
Will the above malloc automatically allocate memory for the inner struct as well? Also, I'm facing a weird problem here. After I free the header, I'm still able to print the values of head->HOPS[i].h_ip. Should I explicitly free the inner struct as well so that even the values get cleared?
Yes, it allocates memory for the inner structure. And you need not free the inner structure separately.
If you have a pointer defined inside your structure, in that case you have to allocate separately for that pointer member of the structure and free that separately.
Consider freeing memory as a black box. All what you know is that after freeing you shouldn't refer to freed memory.
You may find that that memory block still exists and still contains some old values. That's ok: it just was marked as freed and probably it will be used again soon by allocator.
For example when you call malloc again and realized that just allocated block contains values from the old structure. It happens and that's alright. Just use this block as usually.
So, after the problem with the wrong declaration of head was resolved:
free returns a previously allocated memory block to the heap. It does not clear anything (for performance reasons). However, you are not supposed to access that block anymore afterwards. Doing so results in undefined behaviour and might let your computer fly out of the window.
Worst that can happen is ... nothing ... Yes, you might even not notice anything strang happens. However, that does not mean your program run correctly, it just does not show any symptoms.
To catch illegal accesses, you might set the pointer to NULL once you freed the object it points to. Some operating systems catch accesses to addresses near the null pointer address, but there is no guarantee. It is a good practice anyway and does no harm.
For your other question: malloc allocates a block of memory large enough to store that many bytes you passed as argument. If it cannot, it will return a null pointer. You should always check if malloc & friends returned a valid pointer (i.e. not a null pointer).
int *p = malloc(sizeof(int));
if ( p == NULL ) {
error: out of memory
}
...
Notice the omission of the cast of the result of malloc. In C you should not cast void * as returned by malloc & friends (but also elsewhere). As much as you did not for free(head). Both take the same type: void *, btw. (so why cast one and not the other?). Note that in C any object pointer can freely be assigned to/from void * without cast. Warning functions are no objects in the C standard!
Finally: sizeof(HEADER) returns the size of the struct. Of course that include all fields. A nested struct is a field. A pointer to another struct is a field. For the latter, however note: the pointer itself is a field, but not what it points to! If that was another struct, you have to malloc that seperately **and also free seperately (remember what I wrote above).
But as you do not have pointer inside your struct, that is not your problem here. (keep it in mind, if you continue programming, you will eventually need that!)
I have a fairly simple question on allocating memory for a struct in c and I've tried looking online, but I wasn't able to find anything. The struct is defined as:
typedef struct cblock_ {
....
} cblock, *Cblock;
When allocating memory, I've tried
Cblock new_block = malloc(sizeof(struct cblock_));
However, I keep getting getting a memory corruption error. I've tried changing the parameter of sizeof to different things, but everything is getting the same memory corruption error. What am I doing wrong?
****EDIT****
So after running valgrind, I am getting quite a bit of "invalid write of size 4" or "invalid read of size 4" throughout my code.
It's probably too much to post all of it but here's one spot where valgrinds gives me a "invalid write of size 4"
static Ablock agroup_main;
typedef struct ablock_ {
int length;
int num;
...
} ablock, *Ablock;
void init_groups() {
agroup_main = malloc(sizeof(Ablock));
agroup_main->length = DEFAULT_GROUP_LENGTH;
agroup_main->num = DEFAULT_GROUP_NUM;
}
Valgrind is saying on the line setting length that it's an invalid write of size 4, and the address is 0 bytes after a block of size 4 alloc'd. For num, it's the same except the address is 4 bytes after a block of size 4 alloc'd. I don't really understand this either, since length is just an int, and to me, the error sounds like I'm suppose to allocate memory for it...
The memory corruption is probably because of an earlier incorrect malloc (e.g. with a too small size), premature free, or genuine buffer overflow (or uninitialized pointer dereference).
Use a memory leak detector. On Linux, try valgrind
Your malloc for Cblock looks ok. The bug is probably elsewhere. Don't forget to compile with all warnings and debug info (e.g. gcc -Wall -g). Use also a debugger (e.g. gdb). You might want to disable ASLR to ease debugging (and have more reproducible runs).
You should test the result of malloc:
cblock* new_block = malloc(sizeof(struct cblock_));
if (!new_block) {
perror("malloc cblock");
exit(EXIT_FAILURE);
}
and I think you should mark clearly all the pointers in your code (so I prefer cblock* instead of Cblock which I find confusing, and which should at least be named CblockPtr).
BTW, you have been bitten by that confusion:
agroup_main = malloc(sizeof(Ablock)); // WRONG!
is incorrect, since Ablock is a pointer type (on Linux/PC, all pointers have the same size, which is 8 bytes on x86-64). You mean
agroup_main = malloc(sizeof(ablock));
if (!agroup_main)
{ perror("malloc ablock"); exit (EXIT_FAILURE); };
You really should loose the bad habit of naming pointer types in a way hiding their pointerness (and with a name similar to the pointed data).
This:
agroup_main = malloc(sizeof(Ablock));
is clearly wrong, since the type Ablock is struct ablock_ *, i.e. a pointer. You're just allocating the size of the pointer, not the size of the object being pointed at.
You should always write it like this:
agroup_main = malloc(sizeof *agroup_main);
that uses sizeof on the proper type, the type that the pointer receiving the return value points at.
I also stronly recommend against typedefing away the pointer like that, since it adds confusion. Pointers are important in C, hiding them often makes things harder to understand and follow, thus increasing the risk of error. The question "is this an object, or a pointer to an object?" is very important, and you must be able to answer it quickly and correctly, all the time.
I am trying to learn dynamic memory allocation and structures and I have some questions.
First of all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int *number;
number = malloc(1*sizeof(int));
int a;
for(a=0;a<150;a++)
{
number[a]=a;
printf("%d ",number[a]);
}
return 0;
}
In this sample I planned it to give me error. Because I allocated it to size of 1 integer, then I wrote it way too much integers. Shouldn't it give me an error? Can you explain this with detail please?
struct people
{
char *name;
int age;
char *personalInfo;
} human[3];
When I define a structure like this, how can I allocate it to keep more than 3 human? How can I change it to something like human[20] or more? In case if the answer is writing *human instead of human[3], how should I allocate it? Like malloc(number*sizeof(char)*sizeof(int)*sizeof(char))?
And one more thing, in second example do I need to allocate name and personalInfo pointers?
In this sample i planned it to give me error.
You can't "plan to give an error". You're correct to say that the code is wrong because you are writing past the end of the array, but C has no bounds checking -- accessing the array is simply undefined behavior, which means that it can do literally anything -- it can pretend to work fine or it can crash, or it can cause demons to fly out of your nose.
How can i change it to something like human[20] or more?
Well... that's exactly how:
struct people {
// members here
} human[20];
I don't see why the number "3" is so special. If you want to allocate memory dynamically, you would do it the way you would do in the case of every other data type: use the sizeof operator:
struct people *human = malloc(sizeof(human[0]) * number_of_people);
or
struct people *human = malloc(sizeof(struct people) * number_of_people);
C does not provide compile-time or run-time bounds checking of arrays. The program must perform its own bound checking. If you write beyond the end of an array, your program will have undefined behavior. In practice it means that you're corrupting your process' memory by writing to uninitialized areas or areas that are used by allocators for bookkeeping. This can cause the program to crash immediately, crash on exit, or can overwrite the values of other (possibly unrelated) variables in the heap.
To allocate a variable number of people structures, you can do this:
struct people *humans;
humans = malloc(N * sizeof(struct people));
// humans now points to an array of N `people`
For your last question, yes, you must allocate space for those strings, unless you're simply using those pointers to point to strings defined/allocated elsewhere. Note this means that even in the code above where I allocate N objects, I still haven't allocated any space for the strings, and can't write to them until I do so.
struct people
{
char *name;
int age;
char *personalInfo;
};
struct people *human;
human = malloc(sizeof(*human) * 20);
In this sample i planned it to give me error. because i allocated it to size of 1 integer, then i wrote it way too much integers. Shouldn't it give me an error? Can you explain this with detail please?
No, it shouldn't. This is undefined behavior, which may lead to a crash at runtime, but the compiler will neither warn you about it nor produce any errors. You can detect errors like this by running your program in a memory profiler, such as valgrind.
When i define a structure like this, How can i allocate it to keep more than 3 human? How can i change it to something like human[20] or more?
Like this:
struct people *human = malloc(20 * sizeof(struct people));
Like malloc( number*sizeof(char)*sizeof(int)*sizeof(char) ) ?
Besides being too inconvenient, adding up sizes of individual fields may not produce the correct size, because the compiler is allowed to pad your struct to optimize access to its fields. That is why you need to use sizeof(struct people).
The first example invokes undefined behavior.
ยง6.5.6/8: If both the pointer operand and the result point to elements of the same array
object, or one past the last element of the array object, the evaluation shall not
produce an overflow; otherwise, the behavior is undefined
If you want to allocate for 20 humans, you can do...
typedef struct people
{
char *name;
int age;
char *personalInfo;
}People;
People *human;
human = malloc(sizeof(*human) * 20);
I'm pretty sure I'm doing nothing wrong, but thought I'd ask anyway.
We have:
struct some_struct **array_of_ptrs = calloc (num, sizeof (struct some_struct*));
Now assume I just point each of these pointers in the 'array' to a struct some_struct. Now surely to free up the memory, I just do:
free (array_of_ptrs);
Surely this is perfectly acceptable? The reason I ask is because I am doing something similar in my code and gdb is complaining of a free error.
This looks correct, as long as you realize that you're getting an array of pointers, not an array of structures, and you have to assign the pointers yourself. It sounds like that's what you're doing.
Also remember you can assign from array_of_ptrs[0] up to array_of_ptrs[num-1]. If you assign array_of_ptrs[num] you're in trouble.
Yes, what you're doing here looks correct. You are allocating an array of num pointers. So, assuming a 4 byte pointer, 4 * num bytes, all initialized to zero. If you then assign them each to another pointer, that shoudln't create a problem when you free the pointer list.
What exactly is gdb complaining about? Could it be complaining about what these pointers are pointing to going unfreed? Freeing the pointer list will not free what they each point to, if the actual structs themselves were dynamically allocated.
If you do free(array_of_ptrs); then you are in affect creating a memory leak since each entry has a pointer in that array of pointers, it would be worth your while to do a free(...); on each pointer that you have malloc'd firstly, then issue the final free(array_of_ptrs);. This is quite a similar thing when dealing with a linked list using pointers
while (!*array_of_ptrs){
struct *some_ptr_to_struct = *array_of_ptr;
free(some_ptr_to_struct);
*array_of_ptrs++;
}
free(array_of_ptrs);
Hope this helps,
Best regards,
Tom.
Assuming all of the (struct somestruct *) pointers point to memory that's already been allocated, yes, it looks correct.
As for the error, what version of gcc are you using? I tested the code on 4.3.3 and it compiles with no complaints, even with -Wall -pedantic.