realloc() invalid pointer glibc error - pointers

I'm new to pointers and realloc. I know what is going wrong, but I don't know how to solve it.
I create a struct with an array of pointers:
struct DB_SLOT
{
MYSQL *MYSQL_Connection[10];
char *DB_NAME_Connection[10];
};
struct DB_SLOT DB_Conn_SLOT;
I allocate memory with realloc in a loop and (this is where it is getting wrong) I print the address of pointer 2 on the screens.
If I then try to realloc the same amount of memory (just for test purposes). it gives a glibc invalid pointer. Before realloc I print the address of pointer 2 again and it is not the same.
The code for this:
int MallocLoop;
for (MallocLoop = 0;MallocLoop < 10;MallocLoop++)
{
DB_Conn_SLOT.MYSQL_Connection[MallocLoop] = realloc(DB_Conn_SLOT.MYSQL_Connection[MallocLoop],(sizeof(MYSQL)));
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop]=realloc(DB_Conn_SLOT.DB_NAME_Connection[MallocLoop],(sizeof(char)));
if (MallocLoop == 2)
{
printf("pointer 1 %d \n",DB_Conn_SLOT.DB_NAME_Connection[MallocLoop]);
}
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop] ="\0";
}
MallocLoop = 2;
printf("pointer 2 %d \n",DB_Conn_SLOT.DB_NAME_Connection[MallocLoop]);
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop] = realloc(DB_Conn_SLOT.DB_NAME_Connection[MallocLoop], (sizeof(char)));
The result of printing the address of the pointer results in 2 different addresses. How do i solve this??

You have the following two lines:
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop]=realloc(...); ...
DB_Conn_SLOT.DB_NAME_Connection[MallocLoop] ="\0";
Let's simplify this to:
p = realloc(...);
p = "\0";
The first line makes p point at dynamically allocated memory block. The second line leaks that memory (you no longer have a pointer to it), and makes p point to a block of memory inside the .data section.
When you loop again, and pass the .data pointer to realloc, it correctly complains: it is not valid to pass non-dynamically allocated memory to realloc.
What you probably wanted to do was this:
p = realloc(...);
p[0] = '\0';
That makes p point to a dynamically allocated memory block, and makes that block be an empty string.

Related

Memory allocation for Pointer

In which section memory is allocated if I write something like
1. int *ptr;
*ptr = 22;
2. int *ptr = new int(22);
What I Understand is when we use keyword new then memory is get reserved into Heap and that reserved memory address is get returned .
But what happened in case we didn't use keyword new ?? Where memory is get allocated ??
is Both Syntax is Same ?? If No, what is Exact difference between these two statement ??
You code examples can be rephrased as follows:
1st:
int * ptr;
*ptr = 22;
2nd:
int * ptr;
ptr = new int; //the only difference
*ptr = 22;
What happens in the second one:
int * ptr; means create variable capable of storing address of int variable. For now variable isn't initialized, so it stores garbage. If you interpret garbage as pointer, it can points anywhere (it can be 0, or 0xabcdef11, or 0x31323334, or literally ANYTHING which is left on non-cleared memory form previous usage)
ptr = new int; means "allocate memory area capable of holding int and store its address in ptr variable". Since this line, ptr points to specific memory
*ptr = 22; means put value 22 to memory pointed by ptr.
In the first example you create variable, but don't initialize it. ptr contains garbage, but you ask to interpret it as address and store 22 to this address. What can happen:
address is invalid (e.g. 0, or out of address range, or points to protected memory) => program crashes
address is valid and writable, but memory area is used by another part of the program: you'll write 22, but it will corrupt someone's data, result totally unpredictable.
address is valid and writable, memory area isn't in use. You'll write 22, but you aren't guaranteed to read it back. Memory can become used for different purpose and 22 will be overwritten.
anything else. All this is actually an undefined behavior, everything is possible.
That's why it's always recommended to initialize pointer immediately:
int * ptr = NULL; //or better "nullptr" starting from C++11
Attempt to store value *ptr = 22; will at least explicitly crash the program.

Understanding the method for OpenCL reduction on float

Following this link, I try to understand the operating of kernel code (there are 2 versions of this kernel code, one with volatile local float *source and the other with volatile global float *source, i.e local and global versions). Below I take local version :
float sum=0;
void atomic_add_local(volatile local float *source, const float operand) {
union {
unsigned int intVal;
float floatVal;
} newVal;
union {
unsigned int intVal;
float floatVal;
} prevVal;
do {
prevVal.floatVal = *source;
newVal.floatVal = prevVal.floatVal + operand;
} while (atomic_cmpxchg((volatile local unsigned int *)source, prevVal.intVal, newVal.intVal) != prevVal.intVal);
}
If I understand well, each work-item shares the access to source variable thanks to the qualifier "volatile", doesn't it?
Afterwards, if I take a work-item, the code will add operand value to newVal.floatVal variable. Then, after this operation, I call atomic_cmpxchg function which check if previous assignment (preVal.floatVal = *source; and newVal.floatVal = prevVal.floatVal + operand; ) has been done, i.e by comparing the value stored at address source with the preVal.intVal.
During this atomic operation (which is not uninterruptible by definition), as value stored at source is different from prevVal.intVal, the new value stored at source is newVal.intVal, which is actually a float (because it is coded on 4 bytes like integer).
Can we say that each work-item has a mutex access (I mean a locked access) to value located at source address.
But for each work-item thread, is there only one iteration into the while loop?
I think there will be one iteration because the comparison "*source== prevVal.int ? newVal.intVal : newVal.intVal" will always assign newVal.intVal value to value stored at source address, won't it?
I have not understood all the subtleties of this trick for this kernel code.
Update
Sorry, I almost understand all the subtleties, especially in the while loop :
First case : for a given single thread, before the call of atomic_cmpxchg, if prevVal.floatVal is still equal to *source, then atomic_cmpxchg will change the value contained in source pointer and return the value contained in old pointer, which is equal to prevVal.intVal, so we break from the while loop.
Second case : If between the prevVal.floatVal = *source; instruction and the call of atomic_cmpxchg, the value *source has changed (by another thread ??) then atomic_cmpxchg returns old value which is no more equal to prevVal.floatVal, so the condition into while loop is true and we stay in this loop until previous condition isn't checked any more.
Is my interpretation correct?
If I understand well, each work-item shares the access to source variable thanks to the qualifier "volatile", doesn't it?
volatile is a keyword of the C language that prevents the compiler from optimizing accesses to a specific location in memory (in other words, force a load/store at each read/write of said memory location). It has no impact on the ownership of the underlying storage. Here, it is used to force the compiler to re-read source from memory at each loop iteration (otherwise the compiler would be allowed to move that load outside the loop, which breaks the algorithm).
do {
prevVal.floatVal = *source; // Force read, prevent hoisting outside loop.
newVal.floatVal = prevVal.floatVal + operand;
} while(atomic_cmpxchg((volatile local unsigned int *)source, prevVal.intVal, newVal.intVal) != prevVal.intVal)
After removing qualifiers (for simplicity) and renaming parameters, the signature of atomic_cmpxchg is the following:
int atomic_cmpxchg(int *ptr, int expected, int new)
What it does is:
atomically {
int old = *ptr;
if (old == expected) {
*ptr = new;
}
return old;
}
To summarize, each thread, individually, does:
Load current value of *source from memory into preVal.floatVal
Compute desired value of *source in newVal.floatVal
Execute the atomic compare-exchange described above (using the type-punned values)
If the result of atomic_cmpxchg == newVal.intVal, it means the compare-exchange was successful, break. Otherwise, the exchange didn't happen, go to 1 and try again.
The above loop eventually terminates, because eventually, each thread succeeds in doing their atomic_cmpxchg.
Can we say that each work-item has a mutex access (I mean a locked access) to value located at source address.
Mutexes are locks, while this is a lock-free algorithm. OpenCL can simulate mutexes with spinlocks (also implemented with atomics) but this is not one.

Will an array of pointers be equal to an array of chars?

I have got this code:
import std.stdio;
import std.string;
void main()
{
char [] str = "aaa".dup;
char [] *str_ptr;
writeln(str_ptr);
str_ptr = &str;
*(str_ptr[0].ptr) = 'f';
writeln(*str_ptr);
writeln(str_ptr[0][1]);
}
I thought that I am creating an array of pointers char [] *str_ptr so every single pointer will point to a single char. But it looks like str_ptr points to the start of the string str. I have to make a decision because if I am trying to give access to (for example) writeln(str_ptr[1]); I am getting a lot of information on console output. That means that I am linking to an element outside the boundary.
Could anybody explain if it's an array of pointers and if yes, how an array of pointers works in this case?
What you're trying to achieve is far more easily done: just index the char array itself. No need to go through explicit pointers.
import std.stdio;
import std.string;
void main()
{
char [] str = "aaa".dup;
str[0] = 'f';
writeln(str[0]); // str[x] points to individual char
writeln(str); // faa
}
An array in D already is a pointer on the inside - it consists of a pointer to its elements, and indexing it gets you to those individual elements. str[1] leads to the second char (remember, it starts at zero), exactly the same as *(str.ptr + 1). Indeed, the compiler generates that very code (though plus range bounds checking in D by default, so it aborts instead of giving you gibberish). The only note is that the array must access sequential elements in memory. This is T[] in D.
An array of pointers might be used if they all the pointers go to various places, that are not necessarily in sequence. Maybe you want the first pointer to go to the last element, and the second pointer to to the first element. Or perhaps they are all allocated elements, like pointers to objects. The correct syntax for this in D is T*[] - read from right to left, "an array of pointers to T".
A pointer to an array is pretty rare in D, it is T[]*, but you might use it when you need to update the length of some other array held by another function. For example
int[] arr;
int[]* ptr = &arr;
(*ptr) ~= 1;
assert(arr.length == 1);
If ptr wasn't a pointer, the arr length would not be updated:
int[] arr;
int[] ptr = arr;
ptr ~= 1;
assert(arr.length == 1); // NOPE! fails, arr is still empty
But pointers to arrays are about modifying the length of the array, or maybe pointing it to something entirely new and updating the original. It isn't necessary to share individual elements inside it.

C functions returning an array

Sorry for the post. I have researched this but..... still no joy in getting this to work. There are two parts to the question too. Please ignore the code TWI Reg code as its application specific I need help on nuts and bolts C problem.
So... to reduce memory usage for a project I have started to write my own TWI (wire.h lib) for ATMEL328p. Its not been put into a lib yet as '1' I have no idea how to do that yet... will get to that later and '2'its a work in progress which keeps getting added to.
The problem I'm having is with reading multiple bytes.
Problem 1
I have a function that I need to return an Array
byte *i2cBuff1[16];
void setup () {
i2cBuff1 = i2cReadBytes(mpuAdd, 0x6F, 16);
}
/////////////////////READ BYTES////////////////////
byte* i2cReadBytes(byte i2cAdd, byte i2cReg, byte i2cNumBytes) {
static byte result[i2cNumBytes];
for (byte i = 0; i < i2cNumBytes; i ++) {
result[i] += i2cAdd + i2cReg;
}
return result;
}
What I understand :o ) is I have declared a Static byte array in the function which I point to as the return argument of the function.
The function call requests the return of a pointer value for a byte array which is supplied.
Well .... it doesn't work .... I have checked multiple sites and I think this should work. The error message I get is:
MPU6050_I2C_rev1:232: error: incompatible types in assignment of 'byte* {aka unsigned char*}' to 'byte* [16] {aka unsigned char* [16]}'
i2cBuff1 = i2cReadBytes(mpuAdd, 0x6F, 16);
Problem 2
Ok say IF the code sample above worked. I am trying to reduce the amount of memory that I use in my sketch. By using any memory in the function even though the memory (need) is released after the function call, the function must need to reserve an amount of 'space' in some way, for when the function is called. Ideally I would like to avoid the use of static variables within the function that are duplicated within the main program.
Does anyone know the trade off with repeated function call.... i.e looping a function call with a bit shift operator, as apposed to calling a function once to complete a process and return ... an Array? Or was this this the whole point that C does not really support Array return in the first place.
Hope this made sense, just want to get the best from the little I got.
BR
Danny
This line:
byte *i2cBuff1[16];
declares i2cBuff1 as an array of 16 byte* pointers. But i2cReadBytes doesn't return an array of pointers, it returns an array of bytes. The declaration should be:
byte *i2cBuff1;
Another problem is that a static array can't have a dynamic size. A variable-length array has to be an automatic array, so that its size can change each time the function is called. You should use dynamic allocation with malloc() (I used calloc() instead because it automatically zeroes the memory).
byte* i2cReadBytes(byte i2cAdd, byte i2cReg, byte i2cNumBytes) {
byte *result = calloc(i2cNumBytes, sizeof(byte));
for (byte i = 0; i < i2cNumBytes; i ++) {
result[i] += i2cAdd + i2cReg;
}
return result;
}

Where's the memory leak?

So I'm learning pointers and having a difficult time identifying the memory leak here. I confess I have never used malloc() before and am new to pointer arithmetic. Thanks in advance.
/*filename: p3.c */
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *buffer;
char *p;
int n;
/* allocate 10 bytes */
buffer = (char *) malloc(10);
p = buffer;
for (n=0; n<=10; n++)
*p++ = '*';
p = buffer;
for (n=0; n <=10; n++)
printf("%c ", *p++);
return 0;
}
The rule is rather simple, for every malloc there must be a free. If you have more mallocs than frees you forgot to de-allocate memory and so you have a memory leak. If you have more frees than mallocs you're trying to de-allocate memory that has already been de-allocated and that's not something you want.
You simply need to free your buffer by using the free() function, when you don't need the buffer anymore:
/* ... */
free( buffer );
return 0;
}
Simply remember to balance each call to malloc with a call to free, when the memory is not used anymore.
The operations on your p variable won't affect buffer. They are two pointers pointing to the same area (at start), but they're still two distinct variables. So incrementing p won't increment buffer.
So nothing wrong with the pointer operations on p, except the fact you are writing out of bounds, as stated by Daniel Fisher in the comments of your question.
Also note that you should also always check for NULL, after the malloc call, as malloc may fail. It's pretty rare nowadays, but if it fails, your program will probably crash, as you will then dereference a NULL pointer:
buffer = malloc( 10 );
if( buffer == NULL )
{
/* Error management - Do not use buffer */
}
The cast to char * is not needed on malloc, unless you are dealing with C++. In C, it's valid to assign a void pointer to another pointer type.
It is not n<=10 you want, but n<10.
You call malloc and never call free. Of course it leaks.
In principle, every single allocation you request from the alloc family of function should be freeed as soon as you are done with them.
Buffers that you continue to use to up to the termination of the program are formally leaks, but not a problem as long as you are allocating a well defined number of them. That includes what you are doing here.

Resources