Easy way to deal with free in an array [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
When I have a function that gets a pointer int *vector with a couple int values. I want to delete element number n. So I will use free() on that element. The problem I have now that there is a "hole" in my array of int values. Is there an easy way that I dont have this problem or do I really have to make a new int pinter and reorder my vector?

Given a function of this form:
void delete_element(int *vector, size_t index) {
// ...
}
The actual argument corresponding to vector is expected to be a pointer to a series of one or more (implied: index + 1 or more) contiguous ints. This could be part or all of an ordinary int array, or it could be a dynamically allocated block. If the former, then you cannot free any part of the space at all. If the latter, then you can free or reallocate the whole space, but not just the part associated with one element.
To avoid the deletion leaving a hole in your array, you need to move the later elements down, and to do that, you need to know how many elements there are in total. Therefore, you need a more informative function signature, perhaps something like this:
void delete_element(int *vector, size_t *size, size_t index) {
// ...
}
The actual deletion might involve simply using memmove() to move the later elements (overwriting the one to be deleted), and then decrementing the size. With respect to the latter, note that I suggest passing a pointer to the vector size, so that the function can modify the caller's copy.
If you want also to shrink the allocation then you need to do a bit more work (involving calling realloc(), and communicating the revised value of vector back to the caller), but note that in that case your function will not work on ordinary arrays.

There is no way to free() part of a block returned by malloc(). If you want to delete record[n], you need to copy record[n+1]...record[last] into the array.
If you really need to free() each element, you must first malloc() each element.

Related

A few questions about dynamic memory allocation [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
If I dynamically define an array inside a loop, and give it different values each time, and I also don't need this array after the loop ends, do I need to free the array's space each time?
When I dynamically allocate memory for an array of strings, for example, do I also need to allocate memory for each of its elements (strings)?
Let's say i have these 2 dynamically allocated arrays:
char *** arr = { {....}, {....},{.....},.... };
char ** newArr = { ......... };
can I do this? (x is an index of arr):
arr[x] = newArr;
and if yes, what will happen to the memory of the previous element I just switched?
Your title uses the term dynamic memory allocation, whereas some if your detail questions use different terminology and / or use syntax that suggests automatic or static allocation instead. Dynamic allocation involves directly or indirectly using an allocation function such as malloc(), calloc(), or realloc(), and that is primarily what I will be talking about.
If I dynamically define an array inside a loop, and give it different values each time, and I also don't need this array after the
loop ends, do I need to free the array's space each time?
Yes.
Each dynamic allocation reserves space that is not already allocated at the time of the call, and that space remains allocated until you free it via free() or the program terminates, whichever comes first. Until it frees that memory, then, the program has less available for future allocations, and if it keeps on allocating then it uses ever more memory. Eventually, it will run out, and before then it is likely to cause performance problems or worse not only for itself, but for other processes, too.
The general rule is that every allocation must be paired with a corresponding free, though you can fudge that a bit for allocations that need to be retained until the program terminates anyway.
When I dynamically allocate memory for an array of strings, for example, do I also need to allocate memory for each of its elements
(strings)?
Maybe.
The question is ambiguous. I suspect that by "strings" you mean pointers to char, but it is essential to understand that strings are null-terminated sequences of chars in memory -- thus, not pointers. One accesses strings via pointers to them, but you must not confuse the pointer with the string to which it points.
If you allocate space in which to store pointers to strings, whether dynamically or otherwise, that yields space for the pointers, not for anything for them to point to. You need to provide separately for the strings themselves. That could mean allocating additional space for those dynamically, too, but it could also mean pointing to strings that were already allocated by some other means.
Let's say i have [...]
char *** arr = { {....}, {....},{.....},.... };
char ** newArr = { ......... };
can I do this? (x is an index of arr):
arr[x] = newArr;
and if yes, what will happen to the memory of the previous element I just switched?
Yes and nothing.
Regardless of how arr and newArr were allocated, yes, you can perform that assignment as long as x is a valid index into arr. It replaces the pointer value stored in arr[x] with the pointer value that at that point is stored in newArr, leaving both pointers pointing to the same thing. This has no effect on the data to which either the original value of arr[x] or its new value points. In particular, it does not cause any memory to be freed, so if the original value of arr[x] pointed to dynamically allocated memory, and you have no other pointer to the same dynamically-allocated block, then that block can no longer be freed. This is called a "memory leak".

Dereferencing a void pointer using its size in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I know that we cannot dereference a void pointer until and unless we typecast it.
void *ptr = call_a_function();
printf("%d",*(int *)ptr);
This informs the datatype of element(in this case its integer) to the compiler so that it can dereference the amount of space required for it(in this case its 4 bytes).
Suppose I dont know the final datatype, however I know the size of datatype. Can I still dereference it using only the size(4 bytes) and not the datatype(not using int)??
In other words is there a way to tell the compiler how many bytes of memory to read by providing the number of bytes to extract and not the datatype??
EDIT -
I needed to swap the contents of two void * pointers.
Got influenced by the regular way of swapping two values i.e storing the value of one pointer in a temporary variable and then proceed with swapping.
Was trying to attempt the same thing without knowing the datatype but only its size( since the function with this swap code accepts size of variable as one parameter ). However after reading the answers and comments, got to realize that I really dont need to dereference it. Probably memcpy is the correct way to go.
Suppose I dont know the final datatype, however I know the size of datatype. Can I still dereference it using only the size(4 bytes) and not the datatype(not using int)??
Since you cannot deduce or assume the data type, you can't dereference the pointer once to get the complete object. However, you can extract each byte and use it anyway you want.
void *ptr = call_a_function();
unsigned char* cptr = (unsigned char*)ptr;
for (int i = 0; i < num_bytes; ++i )
{
unsigned char c = cptr[i];
// Use c
}
In this case, the whole is not the sum of its parts. Casting not only provides the compiler with the size of the data but also how that data is to be interpreted. Suppose you get 4 bytes, this could be a string of three characters with a NULL byte or a signed integer, which could be encoded in big-endian or little-endian depending on the platform. So knowing the size is not sufficient to properly handle the data even if you could tell the compiler how many bytes to read/dereference.

How to calculate no of rows in 2D array using C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
if the given function is as exp:then how to calculate no of rows in the given 2d array input2
void fun(char *input2[])
{
//calculate no of rows and in each row no of column
}
In general no. In C, it's not possible to calculate the size of an array using only a pointer to it.
However, if you're given a limitation, that the array is terminated by zero(^), then you can count the number of values before the zero using a loop. If it is an array of pointers (such as you have), then the terminator could be a pointer to a specific value. For example, a pointer to zero(^).
Without that limitation, you must store the length in a variable.
(^) you may use any specific value, but zero is a good choice for pointers and characterstrings.
In C, array parameters decay into simple pointers, so you have to design your function to also accept the length of the array:
void fun(char *input2[], int input2Len);
If you also define an array length macro you can call fun like this:
#define LEN(arr) ((int) (sizeof (arr) / sizeof (arr)[0]))
char *strings[10];
...
fun(strings, LEN(strings));
it is impossible to know the size of an array passed to function as argument, in form of type function(type array[]), that because array is a pointer to the first element of it. but there is no information about the last element.
to get over this issue. there are many solutions that we can implement. some of them may alter the implementation of the function itself as passing the size of the array in a second parameter. but if we want to keep function definition untouched. leaves to two possibilities:
1) setting the number of elements on the first item;
2) marking the end of the array (usually is an empty item)
it is almost the second one which is most adopted, here is the code to illustrate that:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int mySizeOfArray(char *input[]){
char **p=input; //p point to the first element of array
while(*p){
p++;//int crementing the pointer
}
return p-input;//return the difference between them
}
/*__________________________________________________________
*/
int main(){
char *input2[]={"First","Second","Third",/*Last*/NULL};
printf("Size of input=%d\n",mySizeOfArray(input2));
return 0;
}

C a function that returns an array [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
If I need to write a function that returns an array: int*, which way is better?
int* f(..data..)
or: void f(..data..,int** arr)
and we call f like this: int* x; f(&x);. (maybe they are both the same but I am not sure. but if I need to return an ErrorCode(it's an enum) too, then in the first way f will get ErrorCode* and in the second way, f will return an ErrorCode).
Returning an array is just returning a variable amount of data.
That's a really old problem, and C programmers developed many answers for it:
Caller passes in buffer.
The neccessary size is documented and not passed, too short buffers are Undefined Behavior: strcpy()
The neccessary size is documented and passed, errors are signaled by the return value: strcpy_s()
The buffer size is passed by pointer, and the called function reallocates with the documented allocator as needed: POSIX getline()
The neccessary size is unknown, but can be queried by calling the function with buffer-length 0: snprintf()
The neccessary size is unknown and cannot be queried, as much as fits in a buffer of passed size is returned. If neccessary, additional calls must be made to get the rest: fread()
⚠ The neccessary size is unknown, cannot be queried, and passing too small a buffer is Undefined Behavior. This is a design defect, therefore the function is deprecated / removed in newer versions, and just mentioned here for completeness: gets().
Caller passes a callback:
The callback-function gets a context-parameter: qsort_s()
The callback-function gets no context-parameter. Getting the context requires magic: qsort()
Caller passes an allocator: Not found in the C standard library. All allocator-aware C++ containers support that though.
Callee contract specifies the deallocator. Calling the wrong one is Undefined Behavior: fopen()->fclose() strdup()->free()
Callee returns an object which contains the deallocator: COM-Objects
Callee uses an internal shared buffer: asctime()
Be aware that either the returned array must contain a sentinel object or other marker, you have to return the length separately, or you have to return a struct containing a pointer to the data and the length.
Pass-by-reference (pointer to size or such) helps there.
In general, whenever the user has to guess the size or look it up in the manual, he will sometimes get it wrong. If he does not get it wrong, a later revision might invalidate his careful work, so it doesn't matter he was once right. Anyway, this way lies madness (UB).
For the rest, choose the most comfortable and efficient one you can.
Regarding an error code: Remember there's errno.
Usually it's more convenient and semantic to return the array
int* f(..data..)
If ever you need complexe error handling (e.g., returning errors values), you should return the error as an int, and the array by value.
There is no "better" here: you decide which approach fits the needs of the callers better.
Note that both functions are bound to give a user an array that they allocate internally, so deallocating the resultant array becomes a responsibility of the caller. In other words, somewhere inside f() you would have a malloc, and the user who receives the data must call free() on it.
You have another option here - let the caller pass the array into you, and return back a number that says how many items you put back into it:
size_t f(int *buffer, size_t max_length)
This approach lets the caller pass you a buffer in a static or in the automatic memory, thus improving flexibility.
the classic model is (assuming you need to return error code too)
int f(...., int **arr)
even though it doesnt flow so nicely as a function returning the array
Note this is why the lovely go language supports multiple return values.
Its also one of the reasons for exceptions - it gets the error indicators out of the function i/o space
The first one is better if there is no requirement to deal with an already existent pointer in the function.
The second one is used when you already have a defined pointer that points to an already allocated container (for example a list) and inside the function the value of the pointer can be changed.
If you must call f like int* x; f(&x);, you do not have much of a choice. You must use the second syntax, i.e., void f(..data..,int** arr). This is because you are not using return value anyways in your code.
The approach depends on a specific task and perhaps on your personal taste or a coding convention adopted in your project.
In general, I'd like to pass pointers as "output" parameters instead of return'ing an array for a number of reasons.
You likely want to return a number of elements in the array together with the array itself. But if you do this:
int f(const void* data, int** out_array);
Then if you see the signature first time, you can't quite tell what the function returns, the number of elements, or an error code, so I prefer to do this:
void f(const void* data, int** out_array, int* out_array_nelements);
Or even better:
void f(const void* data, int** out_array, size_t* out_array_nelements);
The function signature must be self-explanatory, and the parameter names help to achieve that.
The output array needs to be stored somewhere. You need to allocate some memory for the array. If you return a pointer to the array without passing the same pointer as argument, then you can't allocate memory on the stack. I mean, you cannot do this:
int f (const void *data) {
int array[10];
return array; /* the array is likely deallocated when the function exits */
}
Instead, you have to do static int array[10] (which is not thread-safe) or int *array = malloc(...) which leads to memory leaks.
So I suggest you to pass a pointer to the array which is already allocated before the function call, like this:
void f(const void *data, int* out_array, size_t* out_nelements, size_t max_nelements);
The benefit is you are free to choose where to allocate the array:
On the stack:
int array[10] = { 0 };
size_t max_nelements = sizeof(array)/sizeof(array[0]);
size_t nelements = 0;
f(data, array, &nelements, max_nelements);
Or in the heap:
size_t nelements = 0;
size_t max_nelements = 10;
int *array = malloc(max_nelements * sizeof(int));
f(data, array, &nelements, max_nelements);
See, with this approach you are free to choose how to allocate the memory.

how to initialize and use a 2d struct in c [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
So what i am trying to do is have an array of lists, here is my code:
typedef struct stackList{
List * list;
} stack;
int main(){
int x;
stack ** stackTable;
for(x=0;x<100;x++)
stackTable[x]=malloc(sizeof(stack*)*100);
}
i get a segmentation fault on the for loop, i would assume the way i am trying to use the struct is wrong. Would i rather in the defintion of the struct use List ** list;
or is there a way to use it the way i am trying to use it
You get segmentation fault because you're accessing stackTable while it is uninitialized. You can't know to what address of memory it points, and you haven't allocated an array to hold the pointers that you are dereferencing.
You need to make stackTable point to a valid array of pointers, in this case I think is convenient to make it be an array:
Stack* stackTable[100];
Now you have an array of pointers to Stack, you can initialize them.
If instead you have just temporarily an array large 100, and you need to make it grow in future, that's how dynamically allocating it:
Stack** stackTable= malloc(100*sizeof(Stack*));
Before trying too hard to play with pointers and dynamic memory I might suggest writing some basic programs using basic 2d arrays. For instance:
char array2d[10][10];
Once you're confortable inserting elements into this array, extracting elements, etc, you can apply all of the same principles to any type.

Resources