malloc - C program - allocates value 0 to integer in gcc - gcc

I have a linked list structure like this
typedef struct list_node {
int data;
struct list_node *next;
}l_node;
void print_list(l_node *head) {
l_node *cur_node = head;
while(cur_node!=NULL) {
printf("%d\t", cur_node->data);
cur_node = cur_node->next;
}
}
void main() {
printf("List");
l_node *new_node = (l_node*)malloc(sizeof(l_node));
print_list(new_node);
}
When I compile gcc linkedlist.c and do ./a.out
I get output
List
0
But when I tried it in VC++, I got error (since I am trying to access invalid memory location in cur_node->next).
So, does malloc of gcc allocate 0 value by default to the integer variable inside the structure? Why I didn't get the same error while doing the same print_list in gcc?

The contents of the memory returned by malloc are not initialized. You cannot read from that memory before you initialize it (by writing to it at least once).
gcc may be "helpfully" zero-initializing the memory, but that behavior isn't required. The Visual C++ C Runtime (CRT) will give you uninitialized memory in a release build (for maximum performance) and memory initialized with the special fill byte 0xcd in a debug build (to help you find where you may be using uninitialized memory).
So, basically, you need to initialize the memory before you use it. If you want the runtime to zero-initialize the heap block before it gives it to you, you may use calloc.

you need to assign new_node->next = NULL because you check if the current node is NULL or not, and malloc does not initialize the allocated space with any value, so there is no gurantee that the value would be initialized. To be safe you need to assign NULL manually to the tail of the linked list, or an invalid pointer.

Related

How to call a c-function that takes a c-struct that contains pointers

From a GO program on a Raspberry PI I'm trying to call a function(Matlab function converted to C function) and the input to the function is a pointer to a struct and the struct contains pointer to a double(data) and a pointer to an int(size) and two int(allocatedSize, numDimensions). I have tried several ways but nothing has worked, when I have passed the compilation it usually throws a panic: runtime error: cgo argument has Go pointer to Go pointer when I run the program.
sumArray.c
/*sumArray.C*/
/* Include files */
#include "sumArray.h"
/* Function Definitions */
double sumArray(const emxArray_real_T *A1)
{
double S1;
int vlen;
int k;
vlen = A1->size[0];
if (A1->size[0] == 0) {
S1 = 0.0;
} else {
S1 = A1->data[0];
for (k = 2; k <= vlen; k++) {
S1 += A1->data[k - 1];
}
}
return S1;
}
sumArray.h
#ifndef SUMARRAY_H
#define SUMARRAY_H
/* Include files */
#include <stddef.h>
#include <stdlib.h>
#include "sumArray_types.h"
/* Function Declarations */
extern double sumArray(const emxArray_real_T *A1);
#endif
sumArray_types.h
#ifndef SUMARRAY_TYPES_H
#define SUMARRAY_TYPES_H
/* Include files */
/* Type Definitions */
#ifndef struct_emxArray_real_T
#define struct_emxArray_real_T
struct emxArray_real_T
{
double *data;
int *size;
int allocatedSize;
int numDimensions;
};
#endif /*struct_emxArray_real_T*/
#ifndef typedef_emxArray_real_T
#define typedef_emxArray_real_T
typedef struct emxArray_real_T emxArray_real_T;
#endif /*typedef_emxArray_real_T*/
#endif
/* End of code generation (sumArray_types.h) */
main.go
// #cgo CFLAGS: -g -Wall
// #include <stdlib.h>
// #include "sumArray.h"
import "C"
import (
"fmt"
)
func main() {
a1 := [4]C.Double{1,1,1,1}
a2 := [1]C.int{4}
cstruct := C.emxArray_real_T{data: &a1[0], size: &a2[0]}
cstructArr := [1]C.emxArray_real_T{cstruct}
y := C.sumArray(&cstructArr[0])
fmt.Print(float64(y))
}
With this example I get panic: runtime error: cgo argument has Go pointer to Go pointer when I run the program.
I do not how to make it work or if it is possible to make it work. I hope someone can help me or give some direction on how to solve this.
Too much for a comment, so here's the answer.
First, the original text:
A direct solution is to use C.malloc(4 * C.sizeof(C.double))to allocate the array of double-s. Note that you have to make sure to call C.free() on it when done. The same applies to the second array of a single int.
Now, your comment to the Mattanis' remark, which was, reformatted a bit:
thanks for giving some pointers. I tried with
a1 := [4]C.double{1,1,1,1}
sizeA1 := C.malloc(4 * C.sizeof_double)
cstruct := C.emxArray_real_T{
data: &a1[0],
size: (*C.int)(sizeA1)
}
y := C.sumArray(cstruct)
defer C.free(sizeA1)
but it gave me the same
answer as before cgo argument
has Go pointer to Go pointer when I
tried to run the program
You still seem to miss the crucial point. When you're using cgo, there are two disjoint "memory views":
"The Go memory" is everything allocated by the Go runtime powering your running process—on behalf of that process. This memory (most of the time, barring weird tricks) is known to the GC—which is a part of the runtime.
"The C memory" is memory allocated by the C code—typically by calling the libc's malloc()/realloc().
Now imagine a not-so-far-fetched scenario:
Your program runs, the C "side" gets initialized and
spawns its own thread (or threads), and holds handles on them.
Your Go "side" already uses multiple threads to run your goroutines.
You allocate some Go memory in your Go code and pass it
to the C side.
The C side passes the address of that memory to one or more of its own threads.
Your program continues to chug away, and so do the C-side threads—in parallel with your Go code.
As a result you have a reasonably classical scenario in which you get a super-simple situation for unsynchronized parallel memory access, which is a sure recepy for disaster on today's multi-core multi-socket hardware.
Also consider that Go is considerably a more higher-level programming language than C; at the bare minimum, it has automatic garbage collection, and notice that nothing in the Go spec specifies how exactly the GC must be specified.
This means, a particular implementation of Go (including the reference one—in the future) is free to allow its GC to move arbitrary objects in the memory¹, and this means updating every pointer pointing into the memory block in its original location to point to the same place in the block's new location—after it was moved.
With these considerations in mind, the Go devs postulated that in order to keep cgo-using programs future-proof², it is forbidden to pass to C any memory blocks which contain pointers to other Go memory blocks.
It's okay to pass Go memory blocks which contain pointers to C memory, though.
Going back to the example from your second comment,
you still allocate the array of 4 doubles, a1, in the Go memory.
Then the statement cstruct := C.emxArray_real_T{...} again allocates an instance of C.emxArray_real_T in the Go memory, and so after you initialize its data field with a pointer to Go memory (&a1[0]), and then pass its address to the C side, the runtime performs its dynamic checks before actually calling into the C side and crashes your program.
¹ This is typical behaviour for the so-called "generational" garbage collectors, for one example.
² That is, you recompile your program with a future version of the Go compiler of the same "major" release, and the program continues to work, unmodified.

How Memory is allocated for member in the example

I was looking at Microsoft site about single inheritance. In the example given (code is copied at the end), I am not sure how memory is allocated to Name. Memory is allocated for 10 objects. But Name is a pointer member of the class. I guess I can assign constant string something like
DocLib[i]->Name = "Hello";
But we cannot change this string. In such situation, do I need allocate memory to even Name using new operator in the same for loop something like
DocLib[i]->Name = new char[50];
The code from Microsoft site is here:
// deriv_SingleInheritance4.cpp
// compile with: /W3
struct Document {
char *Name;
void PrintNameOf() {}
};
class PaperbackBook : public Document {};
int main() {
Document * DocLib[10]; // Library of ten documents.
for (int i = 0 ; i < 10 ; i++)
DocLib[i] = new Document;
}
Yes in short. Name is just a pointer to a char (or char array). The structure instantiation does not allocate space for this char (or array). You have to allocate space, and make the pointer(Name) point to that space. In the following case
DocLib[i]->Name = "Hello";
the memory (for "Hello") is allocated in the read only data section of the executable(on load) and your pointer just points to this location. Thats why its not modifiable.
Alternatively you could use string objects instead of char pointers.

C++ stateful allocator de-allocate issues

This issue is my misunderstanding of how the standard is using my custom allocator. I have a stateful allocator that keeps a vector of allocated blocks. This vector is pushed into when allocating and searched through during de-allocation.
From my debugging it appears that different instances of my object (this*'s differ) are being called on de-allocation. An example may be that MyAllocator (this* = 1) is called to allocate 20 bytes, then some time later MyAllocator (this* = 2) is called to de-allocate the 20 bytes allocated earlier. Abviously the vector in MyAllocator (this* = 2) doesn't contain the 20 byte block allocated by the other allocator so it fails to de-allocate. My understanding was that C++11 allows stateful allocators, what's going on and how do i fix this?
I already have my operator == set to only return true when this == &rhs
pseudo-code:
template<typename T>
class MyAllocator
{
ptr allocate(int n)
{
...make a block of size sizeof(T) * n
blocks.push_back(block);
return (ptr)block.start;
}
deallocate(ptr start, int n)
{
/*This fails because the the block array is not the
same and so doesn't find the block it wants*/
std::erase(std::remove_if(blocks.begin,blocks.end, []()
{
return block.start >= (uint64_t)ptr && block.end <= ((uint64_t)ptr + sizeof(T)*n);
}), blocks.end);
}
bool operator==(const MyAllocator& rhs)
{
//my attempt to make sure internal states are same
return this == &rhs;
}
private:
std::vector<MemoryBlocks> blocks;
}
Im using this allocator for an std::vector, on gcc. So as far as i know no weird rebind stuff is going on
As #Igor mentioned, allocators must be copyable. Importantly though they must share their state between copies, even AFTER they have been copied from. In this case the fix was easy, i made the blocks vector a shared_ptr as suggested and then now on copy all the updates to that vector occur to the same vector, since they all point to the same thing.

Stack overflow i guess while insmod

I have built kernel 2.6.35 on my system with some specific requirement. I also built some app defined module with the same kernel. I booted up the built version and I find it did not work properly as there is some gui and other modules missing problem. But the system booted up and I did a insmod app.ko. I faced a crash. I found out that it is a stack problem. A caller function in the APP is passing address of two local variable. like int a, b; add (&a, &b); I checked the values of &a and &b before passing and it remained non-null but when i receive the same in the calling function, both the &a, &b are NULL or some garbage value. I increased the stack size but nothing happened. When i skipped the function call, I could see that many allocation of memory has also failed. So I think it should be memory problem. Is there anything I should be checking for gcc option to define the stack or check for stack overflow. Any hints on this could help me a lot. Thanks in advance. I just made some abstract examples since the original code section takes lot of time to explain.
main()
{
struct DMAINFO* pDmaInfo;
struct DESC* pDesc;
/* printk("The function aruguments are Desc = %p and DmaInfo %p", &pDesc, &pDmaInfo); */
Create_DMA(&pDesc, &pDmaInfo);
}
void Create_DMA(**ppDesc, **ppDmaInfor)
{
printk("The function aruguments are Desc = %p and DmaInfo %p", ppDesc, ppDmaInfo);
}
The printk statement inside create_DMA gives me NULL values, but the same print statement in the main function before the create_DMA call has some values.
pDesc and pDmaInfo is un-initialed before Create_DMA(), so it contains garbage value and causes the print statement in the main function before the create_DMA call outputs some values.
When Create_DMA() is called, Create_DMA() try to allocation memory and some other resources and put the result at pDesc and pDmaInfo. When Create_DMA() fails, the value of pDesc and pDmaInfo is undefined, depends on process of Create_DMA().
To avoid such problem, you should always init the pDesc and pDmaInfo and write the Create_DMA() carefully.
main()
{
....
struct DMAINFO* pDmaInfo = NULL;
struct DESC* pDesc = NULL;
....
}

What useful things can I do with Visual C++ Debug CRT allocation hooks except finding reproduceable memory leaks?

Visual C++ debug runtime library features so-called allocation hooks. Works this way: you define a callback and call _CrtSetAllocHook() to set that callback. Now every time a memory allocation/deallocation/reallocation is done CRT calls that callback and passes a handful of parameters.
I successfully used an allocation hook to find a reproduceable memory leak - basically CRT reported that there was an unfreed block with allocation number N (N was the same on every program run) at program termination and so I wrote the following in my hook:
int MyAllocHook( int allocType, void* userData, size_t size, int blockType,
long requestNumber, const unsigned char* filename, int lineNumber)
{
if( requestNumber == TheNumberReported ) {
Sleep( 0 );// a line to put breakpoint on
}
return TRUE;
}
since the leak was reported with the very same allocation number every time I could just put a breakpoint inside the if-statement and wait until it was hit and then inspect the call stack.
What other useful things can I do using allocation hooks?
You could also use it to find unreproducible memory leaks:
Make a data structure where you map the allocated pointer to additional information
In the allocation hook you could query the current call stack (StackWalk function) and store the call stack in the data structure
In the de-allocation hook, remove the call stack information for that allocation
At the end of your application, loop over the data structure and report all call stacks. These are the places where memory was allocated but not freed.
The value "requestNumber" is not passed on to the function when deallocating (MS VS 2008). Without this number you cannot keep track of your allocation. However, you can peek into the heap header and extract that value from there:
Note: This is compiler dependent and may change without notice/ warning by the compiler.
// This struct is a copy of the heap header used by MS VS 2008.
// This information is prepending each allocated memory object in debug mode.
struct MsVS_CrtMemBlockHeader {
MsVS_CrtMemBlockHeader * _next;
MsVS_CrtMemBlockHeader * _prev;
char * _szFilename;
int _nLine;
int _nDataSize;
int _nBlockUse;
long _lRequest;
char _gap[4];
};
int MyAllocHook(..) { // same as in question
if(nAllocType == _HOOK_FREE) {
// requestNumber isn't passed on to the Hook on free.
// However in the heap header this value is stored.
size_t headerSize = sizeof(MsVS_CrtMemBlockHeader);
MsVS_CrtMemBlockHeader* pHead;
size_t ptr = (size_t) pvData - headerSize;
pHead = (MsVS_CrtMemBlockHeader*) (ptr);
long requestNumber = pHead->_lRequest;
// Do what you like to keep track of this allocation.
}
}
You could keep record of every allocation request then remove it once the deallocation is invoked, for instance: This could help you tracking memory leak problems that are way much worse than this to track down.
Just the first idea that comes to my mind...

Resources