This question already has answers here:
Initially mallocate 0 elements to later reallocate and measure size
(2 answers)
Closed 6 years ago.
Below code is just an example which I use to come to the point later:
/* Extract digits from an integer and store in an array in reverse order*/
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int oct=316;
int* array=malloc(0*sizeof(int*)); //Step 1
int* temp;
size_t size=0;
while(oct/10>0 || oct%10>0){
temp=realloc(array,++size*sizeof(int)); // Step2 requires Step1
if(temp==NULL){
printf("Can't reallocate memory");
exit(-1);
}
else{
array=temp;
}
array[size-1]=oct%10;
oct/=10;
}
for(int i=0;i<size;i++)
printf("%d\n",array[i]);
return 0;
}
The realloc reference [1] states :
Reallocates the given area of memory. It must be previously allocated
by malloc(), calloc(), realloc()...
Initially I compiled the code without step1 and on running it I got a segmentation fault. Then I included step1, now the code compiles fine. I don't want to allocate some space without finding an integer to store so I have used a size of zero with malloc. However malloc reference [2] states :
If size is zero, the return value depends on the particular library
implementation (it may or may not be a null pointer), but the returned
pointer shall not be dereferenced.
Now, I doubt my implementation is portable. How can I work around this issue?
I tried doing int* array=NULL; but I got a segmentation fault.
You can initiate array to NULL. In the man page for realloc(void *ptr, size_t size) you can read:
If ptr is NULL, then the call is equivalent to malloc(size)
Moreover realloc does not change its parameter. It returns pointer to newly allocated/reallocated space. So, for reallocating you shall use a code like:
array = realloc(array,(++size)*sizeof(int));
if (array == NULL) { some error; }
Related
Edit: solved by kaylums little comment. Thank you!
good morning,
I am relatively new to C still and I'm trying to make a doubly linked list.
I got my program to run properly with all the functions with this kind of element:
the program crashes after either 2 or 3 inserted elements in the list in the calloc() call of my insertElement() function. I don't get any SIGSEGV or anything, the program just stops with a random negative return.
I'll try to give a minimum code example of the function and the function call:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct Element {
char name[30];
}Element;
typedef struct List {
int size;
Element* first;
Element* last;
}List;
Element* insertElement(List* List, char name[30]) {
Element* element;
element = (Element*)calloc(0, sizeof(Element));
strncpy_s(element->name, name, 30);
return element;
}
List globalList;
char name[30];
int main() {
while (true) {
printf("insert the name >>");
if (fgets(name, 30, stdin) != NULL)
name[strcspn(name, "\n")] = 0;
insertElement(&globalList, name);
}
}
is there already something obvious wrong with that basic stuff?
Thank you very much in advance! Any advice would be very much appreciated, have a good day!
element = (Element*)calloc(0, sizeof(Element));
what is 0 in first argument?
actually you ask for 0 number of your type from memory!
here is some explanation about dynamic memory allocation:
Dynamic memory allocation is a process of allocating memory at run time. There are four library routines, calloc(), free(), realloc(), and malloc() which can be used to allocate memory and free it up during the program execution. These routines are defined in the header file called stdlib.h.
What is malloc() ?
It is a function which is used to allocate a block of memory dynamically. It reserves memory space of specified size and returns the null pointer pointing to the memory location.
The pointer returned is usually of type void. It means that we can assign malloc function to any pointer. The full form of malloc is memory allocation.
What is calloc() ?
Calloc() function is used to allocate multiple blocks of memory. It is a dynamic memory allocation function which is used to allocate the memory to complex data structures such as arrays and structures. If this function fails to allocate enough space as specified, it returns will null pointer. The full form of calloc function is contiguous allocation.
Why use malloc() ?
Here are the reasons of using malloc()
You should use malloc() when you have to allocate memory at runtime.
You should use malloc when you have to allocate objects which must exist beyond the execution of the current memory block.
Go for malloc() if you need to allocate memory greater than the size of that stack.
It returns the pointer to the first byte of allocated space.
It enables developers to allocate memory as it is needed in the exact amount.
This function allocates a memory block size of bytes from the heap.
Why use calloc() ?
Here are the reasons of using calloc()
When you have to set allocated memory to zero.
You can use calloc that returns a pointer to get access to memory heap.
Used when you need to initialize the elements to zero to returns a pointer to the memory.
To prevent overflow that is possible with malloc()
Use calloc() to request a page that is known to already be zeroed.
Syntax of malloc()
Here is a Syntax of malloc()
ptr = (cast_type *) malloc (byte_size);
n above syntax, ptr is a pointer of cast_type. The malloc function returns a pointer to the allocated memory of byte_size.
Example of malloc() in C
In the bellow code, sizeof(*ptr) is used to allocate a memory block of 15 integers. In the printf statement, we are finding the value of the 6th integer.
#include<stdlib.h>
#include<stdio.h>
int main(){
int *ptr;
ptr = malloc(15 * sizeof(*ptr));
if (ptr != NULL) {
*(ptr + 5) = 480;
printf("Value of the 6th integer is %d",*(ptr + 5));
}
}
Output:
Value of the 6th integer is 480
Syntax of calloc()
Here is a Syntax of malloc()
ptr = (cast_type *) calloc (n, size);
The above syntax is used to allocate n memory blocks of the same size. After the memory space is allocated, all the bytes are initialized to zero. The pointer, which is currently at the first byte of the allocated memory space, is returned.
Example of calloc() in C
The C language program below calculates the sum of the first ten terms. If the pointer value if null, then the memory space will not be allocated.
For loop is used to iterate the value of a variable "i" and print the sum. Lastly, function free is used to free-up the pointer.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i, * ptr, sum = 0;
ptr = calloc(10, sizeof(int));
if (ptr == NULL) {
printf("Error! memory not allocated.");
exit(0);
}
printf("Building and calculating the sequence sum of the first 10 terms \n");
for (i = 0; i < 10; ++i) { * (ptr + i) = i;
sum += * (ptr + i);
}
printf("Sum = %d", sum);
free(ptr);
return 0;
}
Output:
Building and calculating the sequence sum of the first 10 terms n Sum = 45
I will not extend on the actual problem (specifying 0 as the number of elements requested to calloc()). I will point you to several other things found in your code.
The first problem in reading your code is that you lack to include the file <stdbool.h>, necessary to use the constants true and false and the type bool. I have added it in the first line.
#include <stdbool.h>
Next, you use at several places the value 30 as the size of several objects that are all related. If you decide in the future to change that value, it will be difficult to find all the ocurrences of the constan 30 and change all of them (and the risk you have used also 30 for anything else and it gets changed in the middle)
I have included a constan with the following lines:
#define NAME_LENGTH (30)
and all the definitions:
...
char name[NAME_LENGTH];
in the structure...
Element* insertElement(List* List, char name[NAME_LENGTH]) {
in the prototype of insertElement (you don't need as name is actually defined as char *, not as an array of NAME_LENGTH elements...
On other side, you need to include a pointer on each Element to link each to the next element of the list. This is done right after name:
struct Element *next; /* we need to include struct as the type Element is not yet defined */
Next, include sizeof *element as the second parameter to calloc() and 1 to the first. Better, if you are going to initialize all fields in the Element structure, then it is better to call malloc() (see the final code , posted at the end)
NEVER, NEVER, NEVER cast the value returned by malloc()
(and friends) This is a legacy that causes a lot of
errors, that get undetected (and very difficult to find),
due to the cast. When you cast you tell the compiler:
leave it in my hands, as I know what I'm doing. And this
makes the compiler silent, when it should be complaining.
The problem mainly has to do with forgetting to include
the header file where malloc (and friends) are declared
(<stdlib.h>) and you will take long time to detect and
see why your program has crashed.
For the same reason, don't use the size of the type, when
you can use the pointed to expression as template of the
type. This is because if you change the type of the
pointed to object, you need to remember that here you have
put the type of the object (and you need to change it too)
This way, this expression
will only be bad if you change the object into a non
pointer object. Also, you have requested for 0 elements
of the specified type, which has already been noticed in other answers. This will make calloc() to return NULL, value you don't check in your code, and you try to use it later on. This will crash your program, but in the best case, it is Undefined Behaviour (and a very difficult error to find, so be careful and always check the value returned by malloc()).
Next, don't use strncpy_s() as it is Microsoft specific routine, and isn't included in any standard. A proper substitute has been provided by strncpy():
strncpy(element->name, name, sizeof element->name);
also use the sizeof operator, as it protects you if you decide in the future to change the type of the pointer.
Finally, it is better to use fgets() as the test expression for the while statement in main(). The reason is that you can end the loop when the end of file is detected.
Finally, you code ends as (including the linking of Elements in the linked list):
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define NAME_LENGTH (30)
typedef struct Element {
char name[NAME_LENGTH];
struct Element *next;
} Element;
typedef struct List {
int size;
Element* first;
Element* last;
} List;
Element* insertElement(List* List, char name[NAME_LENGTH]) {
Element* element;
/* NEVER, NEVER, NEVER cast the value returned by malloc
* (and friends) This is a legacy that causes a lot of
* errors, that get undetected (and very difficult to find),
* due to the cast. When you cast you tell the compiler:
* leave it in my hands, as I know what I'm doing. And this
* makes the compiler silent, when it should be complaining.
* The problem mainly has to do with forgetting to include
* the header file where malloc (and friends) are declared
* (<stdlib.h>) and you will take long time to detect and
* see why your program has crashed. */
/* for the same reason, don't use the size of the type, when
* you can use the pointed to expression as template of the
* type. This is because if you change the type of the
* pointed to object, you need to remember that here you have
* put the type of the object. This way, this expression
* will only be bad if you change the object into a non
* pointer object. Also, you have requested for 0 elements
* of the specified type. */
element = malloc(sizeof *element);
/* don't use strncpy_s as it is not standard. Use the sizeof
* operator again, to protect the expression if you change
* the type of element->name */
strncpy(element->name, name, sizeof element->name);
element->next = NULL;
if (List->last) {
List->last->next = element;
List->last = element;
} else {
List->first = List->last = element;
}
return element;
}
List globalList;
char name[NAME_LENGTH];
int main() {
/* if you put the fgets() call as the test of the while
* statement below, you will process each line until you get
* an end of file condition. Then you can do both things: to
* null the occurence of the \n char, and the call to
* insertElement() I have not corrected because it's a
* question of taste. */
printf("insert the name >> ");
while (fgets(name, sizeof name, stdin) != NULL) {
/* sizeof name is better than the constant, as if you
* change the type definition of object name, you have to
* remember that you are using here its size. sizeof
* does the job for you. */
name[strcspn(name, "\n")] = 0;
insertElement(&globalList, name);
printf("insert the name >> ");
}
Element *p;
char *sep = "\n\n{ ";
for (p = globalList.first; p; p = p->next) {
printf("%s\"%s\"", sep, p->name);
sep = ", ";
}
printf(" };\n");
}
This question already has answers here:
Using sizeof with a dynamically allocated array
(5 answers)
Closed 5 years ago.
I´m working on my program, that loads data from external .txt file - it is structure of 3 integers. Now Im struggling with function that allocates memory. I want to allocate memory for structure of 9 members (108 bytes).
My main program was too large to mess with so I created a smaller program to help me more easily figure out what is going on. Previous questions I went through seemed too complicated and unclear to me, that´s why I made my own.
Id like to know why the third printf, prints 4 and how to correctly allocate required memory (108 bytes)
Glad for any advice
#include <stdio.h>
#include <math.h>
int main(){
int object_counter = 9;
typedef struct myStruct {
int name;
int age;
int height;
} myStruct;
myStruct* dynamicStruct;
dynamicStruct = malloc(object_counter*sizeof(myStruct));
if (dynamicStruct == NULL) {
printf("ERROR\n");
return (-1);
} else {
printf("SUCCESS\n");
}
printf("Size is: %lu\n", sizeof(myStruct)); // prints 12, thats 3 times int, OK
printf("Size is: %lu\n", object_counter*sizeof(struct myStruct)); // prints 108, obviously 9 times 4 bytes
printf("Size is: %lu\n", sizeof(dynamicStruct)); // prints 4 ?? (expected 108)
return 0;
}
The sizeof any pointer is constant (8 bytes on my Linux/x86-64 system, which is also the sizeof(uintptr_t), etc....). It is unrelated to the runtime size of the pointed memory zone. In other words, the sizeof operator always gives a compile-time constant (except for VLAs).
You practically need to keep elsewhere the allocated size of a malloc-ed pointer. For example, you could keep the pointer value in one variable, and its allocated size in another variable.
You could consider an abstract data type (using flexible array members) approach like here.
This question already has answers here:
How is the array stored in memory?
(4 answers)
How to access a local variable from a different function using pointers?
(10 answers)
Closed 6 years ago.
I am trying to implement a simple program using a header file where a function in the header file accepts an int array and returns an int array too.
In header.h:
int* point(int a[]);
In header.c:
#include<stdio.h>
#include "header.h"
int* point(int a[])
{
printf("In the point function\n");
int array[4],i;
for(int i=0;i<4;i++)
{
printf("%dth Iteration\n",i);
array[i]=a[i];
}
return array;
}
In test.c:
#include<stdio.h>
#include "header.h"
void main()
{
int *array,i;
int a[]={1,2,3,4};
printf("calling point function\n");
array=point(a);
printf("Back in the main function\n");
for(i=0;i<4;i++)
{
//SEGMENTATION FAULT HERE
printf("%d\n",array[i]);
}
}
I am getting a segmentation fault at the print loop in test.c.
You cannot return arrays from functions. When point() returns, the local array within this function goes out of scope. This array is created on the stack, and will get destroyed once the function finishes returning. All memory associated with it is discarded, and the returned pointer points to a position on the stack that doesn't exist anymore. You need to instead allocate a pointer on the heap, and return that instead. This allows array to be shared across your program.
Instead of:
int array[4];
you need to dynamically allocate a pointer using malloc():
int *array = malloc(4 * sizeof(*array)); /* or sizeof(int) */
if (array == NULL) {
/* handle exit */
}
malloc() allocates requested memory on the heap, and returns a void* pointer to it.
Note: malloc() can return NULL when unsuccessful, so it needs to be checked always. You also need to free() any memory previously allocated by malloc(). You also don't need to cast return of malloc().
Another thing to point out is using the magic number 4 all over your program. This should really be calculated using sizeof(a)/sizeof(a[0]).
You can declare this as a size_t variable in your main():
size_t n = sizeof(a)/sizeof(a[0]);
Or you can use a macro:
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
And simply call ARRAYSIZE(a) everytime you want the size of the array.
The issue has to do with the scope of the array variable that you're returning in your method. Right now you're returning array, a local variable defined in the method, point. However, once point is finished executing, all local variables within the function frame, including array will be discarded from main memory. So even though you still get a memory address from point, there's no telling what could be at that memory address. Therefore, treating array as an int array when printing out its elements will lead to a segmentation fault.
My suggestion to fix this is to allocate memory from the heap using malloc so that array lasts outside the frame of point. The solution should look like this,
int* point(int a[])
{
printf("In the point function\n");
int *array = (int *) malloc(4 * sizeof(int)); //dynamically allocate memory for 4 integers
int i;
for(i=0;i<4;i++)
{
printf("%dth Iteration\n",i);
array[i]=a[i];
}
return array;
}
You could either define array[] as a global variable, or dynamically allocate memory for it as mentioned in the above comments using malloc().
Since array[] is allocated in the function point(), it gets deleted once the function exits. Hence, a reference to the returned pointer causes a segmentation fault.
I'm creating a source files containing buffer functionality that I want to use for my other library that I'm creating.
It is working correctly but I'm having trouble getting rid of the buffer structure that I'm creating in one of the functions. The following snippets should help illustrate my problem:
C header:
//dbuffer.h
...
typedef struct{
char *pStorage;
int *pPosition;
int next_position;
int number_of_strings;
int total_size;
}DBUFF;
...
C source:
//dbuffer.c
...
DBUFF* dbuffer_init(char *init_pArray)
{
//Find out how many elements the array contains
int size = sizeof_pArray(init_pArray);
//Initialize buffer structure
DBUFF *buffer = malloc(sizeof(DBUFF));
//Initialize the storage
buffer->pStorage = malloc( (sizeof(char)) * (size) );
strncpy( &(buffer->pStorage)[0] , &init_pArray[0] , size);
buffer->number_of_strings = 1;
buffer->total_size = size;
buffer->next_position = size; //size is the next position because array allocates elements from 0 to (size-1)
//Initialize the position tracker which keeps record of starting position for each string
buffer->pPosition = malloc(sizeof(int) * buffer->number_of_strings );
*(buffer->pPosition + (buffer->number_of_strings -1) ) = 0;
return buffer;
}
void dbuffer_destroy(DBUFF *buffer)
{
free(buffer->pStorage);
free(buffer);
}
...
Main:
#include <stdio.h>
#include <stdlib.h>
#include "dbuffer.h"
int main(int argc, char** argv)
{
DBUFF *buff;
buff = dbuffer_init("Bring the action");
dbuffer_add(buff, "Bring the apostles");
printf("BUFFER CONTENTS: ");
dbuffer_print(buff);
dbuffer_destroy(buff);
// Looks like it has been succesfully freed because output is garbage
printf("%s\n", buff->pStorage);
//Why am I still able to access struct contents after the pointer has been freed ?
printf("buff total size: %d\n", buff->total_size);
return (EXIT_SUCCESS);
}
Output:
BUFFER CONTENTS: Bring the action/0Bring the apostles/0
��/�
buff total size: 36
RUN SUCCESSFUL (total time: 94ms)
Question:
Why am I still able to access struct contents using the line below after the pointer to the struct has been freed ?
printf("buff total size: %d\n", buff->total_size);
Once you've called free() on the allocated pointer, attempt to make use of the pointer invokes undefined behavior. You should not be doing that.
To quote C11 standard, chapter §7.22.3.4, free() function
The free() function causes the space pointed to by ptr to be deallocated, that is, made
available for further allocation. [..]
It never say's anything about a cleanup, which you might be (wrongly) expecting.
Just to add clarity, calling free() does not always actually free up the allocated physical memory. It just enables that pointer (memory space) to be allocated again (returning the same pointer, for example) for successive calls to malloc() and family. After calling free(), that pointer is not supposed to be used from your program anymore but C standard does not guarantee of a cleanup of the allocated memory.
If any attempt is made to read memory that has been freed can crash your program. Or they might not. As far as the language is concerned, its undefined behaviour.
Your compiler won't warn you about it(or stop you from accessing it). But clearly don't do this after calling free -
printf("buff total size: %d\n", buff->total_size);
As a good practice you can set the freed pointer to NULL .
free() call will just mark the memory in heap as available for use. So you still have the pointer pointing to this memory location but it's not available anymore for you. Thus, the next call to malloc() is likely to assign this memory to the new reservation.
To void this situations normally once you free() the memory allocated to a pointer you should set it to NULL. De-referencing NULL is UB also but at least when debugging you can see tha pointer should not be used because it's not pointing to a valid memory address.
[too long for a comment]
To allow your "destructor" to set the pointer passed to NULL modify your code like this:
void dbuffer_destroy(DBUFF ** buffer)
{
if ((NULL == buffer) || (NULL == *buffer))
{
return;
}
free((*buffer)->pPosition);
free((*buffer)->pStorage);
free(*buffer);
*buffer = NULL;
}
and call it like this:
...
dbuffer_destroy(&buff);
...
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I get the size of an array from a pointer in C?
How can I get the size of a memory block allocated using malloc()?
void func( int *p)
{
// Add code to print MEMORY SIZE which is pointed by pointer p.
}
int main()
{
int *p = (int *) malloc(10 * sizeof(int));
func(p);
}
How can we find MEMORY SIZE from memory pointer P in func() ?
You cannot do this in a portable manner in C. It may not be stored anywhere; malloc() could reserve a region much larger than you asked for, and isn't guaranteed to store any information about how much your requested.
You either need to use a standard size, such as malloc(ARRAY_LEN * sizeof(int)) or malloc(sizeof mystruct), or you need to pass the information around with the pointer:
struct integers {
size_t count;
int *p;
};
void fun(integers ints) {
// use ints.count to find out how many items we have
}
int main() {
struct integers ints;
ints.count = 10;
ints.p = malloc(ints.count * sizeof(int));
fun(ints);
}
There is no inbuilt logic to find the memory allocated for a pointer.
you have to implement your own method for doing it as brian mentioned in his answer.
And yes,you can find the memory leaked using some tools like valgrind on linux.
and on solaris there is a library libumem.so which has a function called findleaks which will tell you how much memory is leaked while the process is in running state.