I have below code. In below code the value 5 gets stored in variable a(i.e abc.a). But I would like to intialize the value in c (i.e abc.c). How to do that? My requirement is to fill the data for c not for a.
typedef struct abc
{
int a;
int b;
int c;
}abc;
typedef struct def{
int *ptr;
abc strpt;
}def;
typedef struct xyz{
int *pointer;
}xyz;
int main()
{
int *temp, tmp;
abc* ab;
tmp = 5;
temp = &tmp;
ab = (abc*)malloc(sizeof(abc));
xyz *x = (xyz*)malloc(sizeof(xyz));
def *de = (def*)malloc(sizeof(def));
x->pointer = (xyz*)temp;
ab = (abc*)x->pointer;
return 0;
}
Please help me.
I'm Affraid some serious lack of understanding pointers manifests in your code. Let me dissect it line by line to make clear where problems occur.
I numbered the statements in order to make easy references, assuming the type declarations as above.
int main()
{
int *temp, tmp;
abc* ab;
/* 1 */ tmp = 5;
/* 2 */ temp = &tmp;
/* 3 */ ab = (abc*)malloc(sizeof(abc));
/* 4 */ xyz *x = (xyz*)malloc(sizeof(xyz));
/* 5 */ def *de = (def*)malloc(sizeof(def));
/* 6 */ x = (xyz*)temp;
/* 7 */ ab = (abc*)x;
return 0;
}
First of all: You never clean up the memory allocated in 3, 4 and 5. Even for a simple test program, you should always take care of stuff like this.
Your first problem is line 6 where you blindly cast a pointer to an object of type int (4 bytes in memory) into a pointer to a structure of type xyz (4 or 8 bytes in memory, different type). What you do here is a complicated way to write x = (xyz*)&tmp;.
An action like that leads to following serious problems:
You just allocated memory in line 4. Now you overwrite this pointer with a pointer to your stack variable. Therefore you can't free the allocated memory anymore ==> Memory leak
Your newly assigned pointer to the stack variable becomes invalid after exiting the scope and can cause undefined behaviour.
Any write attempt to elements of x after line 6 can lead to corruption of the stack (and therefore undefined behaivour) due to a possible size mismatch of elements.
By line 7 you get the same problems again and even worse. The estimated sizeof(abc) is possibly 12 bytes. Accessing any element of abc after this line can lead to stack corruption again.
I still don't understand what you really are looking for but if you "have to" initialize a structure element through pointers there are a several ways:
If the struct ist known you can do it like this:
abc * ab = malloc(sizeof(abc));
if (ab != NULL) {
ab->c = 5;
// -- do other stuff
free(ab); ab = NULL;
}
If you need a pointer to the element 'c' you can do it like this:
int * c_ptr = NULL;
abc * ab = malloc(sizeof(abc));
if (ab != NULL) {
c_ptr = &(ab->c);
*c_ptr = 5;
//-- do other stuff
free(ab); ab = NULL;
}
Are you asking for this:
abc s;
s.c = 5;
That makes c 5. Or you could do thos:
abc s = {0,0,5};
That means, the first two members are initialized to 0, and third one (which is c) is initialized to 5.
Or if you've pointer, then you can do this:
abc *p = malloc(etc);
p->c = 5;
But then avoid using pointers and malloc. Use it when you really need them. In your code, I don't see any reason why you would need it. Use automatic variables, not pointers.
I think you would need to add this before return in your main() to get what you need.
ab->c = *(x->pointer);
Related
I am running ASAN for finding memory leaks in a very big project. I have found out the cause, but do not know how to resolve it. I have made a sample program to make the problem understandable.
In the below program I can only work-around on specified code. For rest of the code it is not possible to do work around.
So please suggest what work around I may have to resolve below ASAN error.
(How to make pointer two as NULL using t1?)
#include<stdio.h>
#include<stdlib.h>
typedef struct l
{
int a, b;
}pack;
void delete_me(pack *ap)
{
free(ap);
}
int main(void)
{
pack **d_ptr = (pack **)malloc(3 * sizeof(pack *));
pack *one, *two, *three;
one = (pack *)malloc(sizeof(pack));
one->a = 1, one->b = 2;
two = (pack *)malloc(sizeof(pack));
two->a = 3, two->b = 4;
three = (pack *)malloc(sizeof(pack));
three->a = 5, three->b = 6;
d_ptr[0] = one;
d_ptr[1] = two;
d_ptr[2] = three;
// I can Only work-around below code (4 lines)
pack *t1 = d_ptr[1]; // For which index t1 would be assigned, is not known before hand
t1->a = 1; t1->b = 2;
printf("a: %d, b: %d\n", two->a, two->b);
delete_me(t1); // How to delete t1 so that corresponding pointer also becomes NULL?
// Work around only till here was possible.
// Below this, No workaround possible.
if (two && (two->a == one->a)) // ASAN ERROR
printf("ERROR\n");
else
printf("It works!\n");
return 0;
}
ASAN Error:
ERROR: AddressSanitizer: heap-use-after-free
Unfortunately your problem isn't really solvable.
When you have multiple copies of the same pointer, e.g.
int *p1 = malloc(sizeof (int));
int *p2 = p1;
int *p3 = p2;
then freeing any of them invalidates all of them:
free(p2);
// Now p1, p2, p3 have invalid values.
// The C standard calls these "indeterminate values"; accessing them has undefined behavior
You can manually set p2 to NULL after freeing, but that still leaves p1 and p3 dangling. You cannot automatically find all copies of a pointer value that may exist anywhere in your program's memory.
You need to restructure the logic of your program. There is no quick and easy fix.
I'm trying to build a structure called PROCESS in C, this struct should contain the ID(id) and waiting time (wt) of the process.
typedef struct PROC{
int id;
int wt;
}PROCESS;
PROCESS *pt = NULL;
Now I want to make more then one instance of this struct like an array.
what I want to do is something like this':
PROCESS pt[10];
pt[0].id = 5;
pt[1].id = 7;
But I want to do it using dynamic memory allocation:
pt = calloc(2,sizeof(PROCESS));
pt[0]->id = 5;
What is my mistake?
pt is a pointer to PROCESS, pt[0] is the first PROCESS object pointed to by pt.
The -> operator to access members of a struct must be used with pointers only, otherwise use .
pt[0].id = 5;
would be correct.1
An since you say you are doing C, you don't need to cast malloc or calloc.
PROCESS *pt = calloc(2, sizeof *pt);
if(pt == NULL)
{
// errror handling
// do not continue
}
pt[0].id = 5;
pt[1].id = 7;
Also don't forget to check the return value of calloc and don't forget to free
the memory later with free(pt);.
Fotenotes
1Note that this would be equivalent to
pt->id = 5;
but if you want to set id of the second element, you would need to do
(pt+1)->id = 7;
but I think it's more readable to do
pt[1].id = 7;
typedef struct process{
int id;
int wt;
}processes;
I would allocate like this->
int numberOfDynamicStructs=2;
processes* myProcesses= calloc(numberOfDynamicStructs,sizeof(processes));
Write->
myProcesses[0].id=1;
myProcesses[1].id=2;
Read->
printf("%d %d",myProcesses[0].id,myProcesses[1].id);
Free when done..
/A
A "Deeltal" keeps track of how many dividers an integer has (count) and keeps them in an array (dividers).
Examples:
value = 8 -> count = 3 and dividers = {1,2,4}
value = 10, count = 3, dividers = {1,2,5}
Hope everything is clear, take a look at the following code:
typedef struct{
int value;
int count;
int* dividers;
} Deeltal;
void free_dividers(Deeltal *g){ /*Deletes the int* dividers of a given Deeltal*/
free (g - > dividers);
}
/* the following two functions have the same purpose: deleting the content of a
given amount of "Deeltal" AND deleting the pointer to it aswell*/
void free_amountOfdeeltal(Deeltal *d, int amount){
int i;
for (i = 0; i < amount; i++){
free_dividers(&d[i]);
}
free(d);
}
void free_amountOfdeeltalVersion2(Deeltal **g, int amount){
int i;
for(i = 0; i < amount; i++){
free_dividers(&(*g)[i]);
}
free(*g);
}
If my main looked something like this
int main(void){
/*EDIT 3/11/2017: forgot to allocate memory for *d and initializing g.
Thanks for pointing this out*/
Deeltal g = 0;
g.value = 6; g.count = 3; g.dividers = {1,2,3};
Deeltal *d = malloc(sizeof(Deeltal));
d->value = 6; d->count = 3; d->dividers = {1,2,3};
free_amountOfdeeltal(&g);
free_amountOfdeeltalVersion2(&d);
}
What is the difference between free_amountOfdeeltal and free_amountOfdeeltalVersion2?
Both should do the same thing: releasing the memory of a Deeltal and also deleting the pointer pointing to that memory.
On a sidenote:
How do you delete the memory as well as the pointer?
Not withstanding calling this function with invalid data as pointed out by others .. I'll attempt to answer the question I think you are asking.
On a sidenote: How do you delete the memory as well as the pointer?
You can't really "delete the pointer" in this context as a pointer is simply a variable that is assigned an address. You delete memory that was allocated to you by passing free a pointer to the memory. Note that free does not modify the value of the pointer at all. (It can't because the pointer is passed by value.) After the call to free the pointer still points to the same memory address.
If what you mean is "how can I assign a meaningful value to the pointer to identify that its memory has already been deleted," then you can use the second form of your function:
void free_amountOfdeeltalVersion2(Deeltal **g, int amount);
and set *g to NULL before returning. You can then use this information than the pointer is NULL to identify the memory has already been deleted.
You didn't allocate any memory for d so your pointer doesn't point to any structure. Therefor, you can't access its properties or free its memory because you didn't reserve it in the first place. There's no way this code could come remotely close to compiling.
First of all you should be allocating memory for a "Deeltal" structure like this:
Deeltal *d = malloc(sizeof(Deeltal));
I recommend you go back and relearn how pointers work, as you're doing some really weird stuff there.
My issue is with nums3 array and why the last for-loop actually prints expected results. The nums3 array as I understand it contains an array of pointers to the struct but these pointers have not yet been initialized to any specific instance of a struct. But in this for-loop I can assign values and see the expected results display.
Also, I've read that with the pointer returned by malloc I can use the [index] after the pointer and iterate over the allocated memory. I assume this feature is using the fact it has a type multiplied by some value and it does the division automatically to know how this block of memory is split up and therefore how far to advance to the next index. But I'm still confused as to why I'm getting expected results on that last for-loop when I haven't initialized or pointed those pointers to anything specific.
I know that if I were to add ** and change the to -> then I could operate on those pointers directly, but with the code now I'm able to use the . operator to access structure members. So, without the ** in the nums3 malloc line, what exactly does the pointer returned from malloc return?
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_MAX 5
int main(void)
{
struct number {
int num1;
int num2;
int num3;
};
struct number n;
n.num1 = 5;
printf("n.num1: %d\n", n.num1);
n.num2 = 6;
printf("n.num2: %d\n", n.num2);
n.num3 = 7;
printf("n.num3: %d\n", n.num3);
struct number nums1[5];
struct number* nums2 = malloc(sizeof(struct number) * ARRAY_MAX);
struct number* nums3 = malloc(sizeof(struct number*) * ARRAY_MAX);
int x;
for(x = 0; x <= 5; x++) {
nums1[x].num1 = x;
nums1[x].num2 = x;
nums1[x].num3 = x;
}
int y;
for(y = 0; y <= ARRAY_MAX; y++) {
nums2[y].num1 = x;
nums2[y].num2 = x;
nums2[y].num3 = x;
}
for(y=0; y<=ARRAY_MAX; y++) {
nums3[y].num1 = y;
nums3[y].num2 = y;
nums3[y].num3 = y;
printf("%d ", nums3[y].num1);
printf("%d ", nums3[y].num2);
printf("%d \n", nums3[y].num3);
}
Here is a simpler test case of my question:
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
int main(void)
{
struct number {
int num1;
};
struct number* n = malloc(sizeof(struct number*) * MAX);
int i;
for(i=0; i<MAX; i++) {
n[i].num1 = i;
printf("%d\n", n[i]);
}
free(n);
}
Result of running this code:
jason smith#jasonS-pc ~/src/c
$ ./a.exe
0
1
2
3
4
jason smith#jasonS-pc ~/src/c
$
Questions:
How does n[i] work with n being the pointer returned from malloc? How does C know what to do with n[i]? How does C know how to get to n[i+1]? Does it look at what sizeof() is being called on and divide by however many times it is multiplied and use that result to know where the next cell starts?
Why does n[i].num1 = i; even compile? If all I have done is specify a block of memory containing size for x number of pointers to the struct (pointers which would be smaller than the size of the struct itself) and certainly have not initialized anything to point to an actual instance of this struct. Why isn't this a syntax or some other compiler generated error? What exists at cell n[i] that .num1 is working on? Doesn't n[i] right now just contain a pointer without a valid address since it's not yet initialized? How do we go from that to n[i].num1 = i? Is it valid syntax to do "some memory address".num1 = "some value"?
I understand this is not the correct way to do this, and you all have provided great information, but I'm still puzzled as to why this code even compiles. It just doesn't make sense to me.
In general, if you access memory incorrectly you cannot expect anything. You can't expect to get the right answer, and you can't expect to get the wrong answer. You can't expect your program to crash and you can't expect it to run. Again, it can do anything.
The error here is that you allocated an array of pointers but then chose the wrong type to hold the result.
// This is wrong!
struct number* nums3 = malloc(sizeof(struct number*) * ARRAY_MAX);
You want this:
struct number **nums3 = malloc(sizeof(struct number*) * ARRAY_MAX);
// ^^
Or really, this way is better:
struct number **nums3 = malloc(sizeof(*nums3) * ARRAY_MAX);
Then you have an array of (uninitialized) pointers to play with. For example,
for (int i = 0; i < ARRAY_MAX; i++) {
nums3[i] = malloc(sizeof(*nums3[i]));
nums3[i]->num1 = i;
nums3[i]->num2 = i;
nums3[i]->num3 = i;
}
or...
for (int i = 0; i < ARRAY_MAX; i++) {
nums3[i] = &nums2[i];
}
Whatever you want.
(We're pretending here that malloc() doesn't return NULL which is not guaranteed.)
You are correct by saying you are not allocating enough space as sizeof(struct number) = 12 while sizeof(struct number*) = 8
Malloc finds a free memory according to the size you asked and (if successful) returns you a pointer to the first address (this is virtual memory). If you exceed the size created you enter the realm of unexpected behavior. Meaning you either will be able to write and read data from the memory or you won't and even if you manage to do that, you can accidentally overwrite areas in memory storing other data.
In this case, although printing passed with no special behavior, when you try to free(nums3) you will get an error.
Also, if you will reverse the order of nums2 and nums3 declaration and print nums2 after nums3 loop, you will probably be able to see this corruption of data.
Hope this is helpful
I have a function that sets values to a struct:
My struct:
struct entry {
char key[MAX_KEY];
int* values;
size_t length;
entry* next;
entry* prev;
};
My function:
// Sets entry values
void command_set(char **commands, int arg_num) {
struct entry e;
e.length++;
strcpy(e.key, commands[1]);
for (int i = 2; i < arg_num; i++) {
e.values[i - 2] = atoi(commands[i]);
}
}
where:
**commands: is a array of strings
arg_num: is how many strings are in the array
key: is the name of the entry
values: are integer values store in the entry
I run the code and I get a segmentation fault 11. I have narrowed it down to the line:
e.values[i -2] = atoi(commands[i]);
I assume that I have to use malloc to allocate memory as I don't appear to have gone out of bounds with my loop. I have tried to understand the correct way to allocate memory however I can't seem to get the syntax correct for allocating sizeof(int) to a dynamic array of integers.
I have tried:
e.values[i - 2] = malloc(sizeof(int));
and
e.values[i - 2] = (int) malloc(sizeof(int));
and
e.values[i - 2] = malloc(sizeof(int *));
However I get the error:
incompatible pointer to integer conversion assigning
to 'int' from 'void *' [-Werror,-Wint-conversion]
You must allocate the whole array:
e.values = malloc(sizeof(int) * (arg_num - 2))
Important: Remember to call free when you're done with the memory or you will have a memory leak.
You have another problem though, unrelated to the one you're asking about.
You do
struct entry e;
e.length++;
When the structure object e is defined, it is uninitialized, all its members will have an indeterminate value. Using such uninitialized data in any way except to initialize it will lead to undefined behavior. And you do use such uninitialized values when you do e.length++.
That increase simply doesn't make any sense in the code as you show it. On the other hand, that function doesn't make a lot of sense anyway since the variable e and all its data will simply "disappear" when the function returns. So I can only assume that it's not the complete function you show us.
To initialize the structure to all zeroes, simply do
struct entry e = { 0 };
as your struct is as follows
struct entry {
char key[MAX_KEY];
int* values;
size_t length;
entry* next;
entry* prev;
};
then you should allocate memory to it as
e.values =(int *)malloc(arg_num*sizeof(int));
like if you have 10 values then you are allocating 10*4 values to it.
and invoke free on it
free(e.values)
when the e or e.values is no more useful. for more information you can see here
Modify the function as below.
void command_set(char **commands, int arg_num) {
struct entry e;
e.length++;
strcpy(e.key, commands[1]);
//here is the memory allocation
e.values = malloc(arg_num-1 * sizeof(int));
for (int i = 0; i < arg_num-1; i++) {
e.values[i] = atoi(commands[i+1]);
}
}