I believe I have a very basic pointer question... I am wanting to use Windows APIs (so things like malloc are out of the question) to create a dynamic block of memory to use for various things, save C strings, integer values, etc. at various offsets within the allocated area.
The code I am using is as follows:
HANDLE hProcess = NULL;
LONG32 *lpHeapAddr = NULL;
hHeap = GetProcessHeap();
lpHeapAddr = (LONG32*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 0xC00);
My question is, how can I access specific offsets within the returned space. The variable lpHeapAddr contains the base address of the memory allocation. I suspected lpHeapAddr[0x10] would give me access to the 16th offset into this allocation. But I'm finding things like this aren't working and I suspect it's simply because my logic or understanding is incorrect:
char some_array[] = {0xED, 0x84, 0x5A, 0x20};
for(i = 0; i < 0x04; i++){
lpHeapAddr[0x30+i] = some_array[i];
}
The values in lpHeapAddr[0x30] are not the values in some_array.
Hopefully this is clear as to what my confusion is, as always, any help is greatly appreciated.
Cheers,
You need to be aware of pointer math;
type *pointer ;
pointer+index; // address=pointer+sizeof(type)*index
pointer[index] // address=pointer+sizeof(type)*index
++pointer ; // address=pointer+sizeof(type)
Here is code:
char *memchar_addr=(char*)(lpHeapAddr[0x30]);
for(i = 0; i < 0x04; i++){
memAddr[i] = some_array[i];
printf("%c\t",memAddr[i]);
}
Here is full code.
#include <stdio.h>
#include "windows.h"
int main()
{
HANDLE hHeap; // heap handle
hHeap=GetProcessHeap();
char some_array[0x3F];
memset(some_array,(int)65,sizeof(some_array));
if (hHeap!=NULL)
{
int *memAddr=NULL; //pointer to memory
memAddr=(int*)HeapAlloc(hHeap,0,0xC00);
if (memAddr!=NULL)
{
int i;
for(i = 0; i < 0x3F; i++){
memAddr[0x20+i] = some_array[i];
printf("%d\t",memAddr[0x20+i]);
}
char some_array2[] = {0xED, 0x84, 0x5A, 0x20};
for(i = 0; i < 0x04; i++){
memAddr[0x30+i] =(int) some_array2[i];
printf("%d\t",memAddr[0x30+i]);
}
if (HeapFree(hHeap,0,memAddr)==0)
printf("free error");
}
}
}
Related
Disclaimer, this is help with a school assignment. That being said, my issue only occurs about 50% of the time. Meaning if I compile and run my code without edits sometimes it will make it through to the end and other times it will not. Through the use of multiple print statements I know exactly where the issue is occurring when it does. The issue occurs in my second call to hugeDestroyer(right after the print 354913546879519843519843548943513179 portion) and more exactly at the free(p->digits) portion.
I have tried the advice found here (free a pointer to dynamic array in c) and setting the pointers to NULL after freeing them with no luck.
Through some digging and soul searching I have learned a little more about how free works from (How do malloc() and free() work?) and I wonder if my issue stems from what user Juergen mentions in his answer and that I am "overwriting" admin data in the free list.
To be clear, my question is two-fold.
Is free(p->digits) syntactically correct and if so why might I have trouble half the time when running the code?
Secondly, how can I guard against this kind of behavior in my functions?
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct HugeInteger
{
// a dynamically allocated array to hold the digits of a huge integer
int *digits;
// the number of digits in the huge integer (approx. equal to array length)
int length;
} HugeInteger;
// Functional Prototypes
int str2int(char str) //converts single digit numbers contained in strings to their int value
{
return str - 48;
}
HugeInteger *parseInt(unsigned int n)
{
int i = 0, j = 0;
int *a = (int *)calloc(10, sizeof(int));
HugeInteger *p = (HugeInteger *)calloc(1, sizeof(HugeInteger));
if(n == 0)
{
p->digits = (int *)calloc(1, sizeof(int));
p->length = 1;
return p;
}
while(n != 0)
{
a[i] = n % 10;
n = n / 10;
i++;
}
p->length = i;
p->digits = (int *)calloc(p->length, sizeof(int));
for(i = 0; i <= p->length; i++, j++)
p->digits[j] = a[i];
return p;
}
HugeInteger *parseString(char *str) //notice datatype is char (as in char array), so a simple for loop should convert to huge int array
{
int i = 0, j = 0;
HugeInteger *p = (HugeInteger *)calloc(1, sizeof(HugeInteger));
if(str == NULL)
{
free(p);
p = NULL;
return p;
}
else
{
for(i=0; str[i] != '\0'; i++)
;
p->length = i;
p->digits = (int *)calloc(p->length, sizeof(int));
for(; i >= 0; i--)
p->digits[j++] = str2int(str[i - 1]);
}
return p;
} //end of HugeInteger *parseString(char *str)
HugeInteger *hugeDestroyer(HugeInteger *p)
{
//printf("No problem as we enter the function\n");
if(p == NULL)
return p;
//printf("No problem after checking for p = NULL\n");
if(p->digits == NULL)
{
free(p);
p = NULL;
return p;
}
//printf("No Problem after checking if p->digits = NULL\n");
//else
//{
free(p->digits);
printf("We made it through free(p->digits)\n");
p->digits = NULL;
printf("We made it through p->digits = NULL\n");
free(p);
printf("We made it through free(p)\n");
p = NULL;
printf("We made it through p = NULL\n");
return p;
//}
//return NULL;
}//end of HugeInteger *hugeDestroyer(HugeInteger *p)
// print a HugeInteger (followed by a newline character)
void hugePrint(HugeInteger *p)
{
int i;
if (p == NULL || p->digits == NULL)
{
printf("(null pointer)\n");
return;
}
for (i = p->length - 1; i >= 0; i--)
printf("%d", p->digits[i]);
printf("\n");
}
int main(void)
{
HugeInteger *p;
hugePrint(p = parseString("12345"));
hugeDestroyer(p);
hugePrint(p = parseString("354913546879519843519843548943513179"));
hugeDestroyer(p);
hugePrint(p = parseString(NULL));
hugeDestroyer(p);
hugePrint(p = parseInt(246810));
hugeDestroyer(p);
hugePrint(p = parseInt(0));
hugeDestroyer(p);
hugePrint(p = parseInt(INT_MAX));
hugeDestroyer(p);
//hugePrint(p = parseInt(UINT_MAX));
//hugeDestroyer(p);
return 0;
}
First of all, really outstanding question. You did a lot of research on topic and generally speaking, solved this issue by yourself, I'm here mainly to confirm your findings.
Is free(p->digits) syntactically correct and if so why might I have trouble half the time when running the code?
Syntax is correct. #Shihab suggested in comments not to release p->digits and release p only, but such suggestion is wrong, it leads to memory leakages. There is a simple rule: for each calloc you must eventually call free, so your current approach in freeing p->digits and then p is totally fine.
However, program fails on a valid line. How is it possible? Quick answer: free can't do its work due to corruption of meta information responsible for tracking allocated/free blocks lists. At some point program corrupted meta information, but this was revealed only on attempt to use it.
As you already discovered, in most implementations memory routines such as calloc results into allocation of buffer with prepended meta-info. You receives pointer to buffer itself, but small piece of information right before this pointer is crucial for further buffer managing (e.g. freeing). Writing 11 integers into buffer intended for 10, you're likely to corrupt meta-info of block following the buffer. Whether corruption actually happens and what would be its consequences, is heavily dependent on both implementation specifics and current memory alignment (what block follows the buffer, what exactly meta-data is corrupted). It doesn't surprise me, that you see one crash per two executions, neither surprises me observing 100% crash reproduction on my system.
Secondly, how can I guard against this kind of behavior in my functions?
Let's start with fixing overflows. There are couple of them:
parseString: loop for(; i >= 0; i--) is executed length+1 times, so p->digits is overflown
parseInt: loop for (i = 0; i <= p->length; i++, j++) is executed length+1 times, so p->digits is overflown
Direct access to memory managing in C++ is error prone and troublesome to debug. Memory leakages and buffers overflows are the worst nightmare in programmers life, it's usually better to simplify/reduce direct usage of dynamic memory, unless you are studying to cope with it, of course. If you need to stick with a lot of direct memory managing, take a look at valgrind, it's intended to detect all such things.
By the way, there is also a memory leakage in your program: each call to parseInt allocates buffer for a, but never frees it.
While playing with the implementation of a hashmap toy example (for fun) I've found a strange behaviour, calloc does not initialize the entire memory block I want to zero, as supposed to do. The following code should produce no output if the entire memory block is zeroed:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define DICT_INITIAL_CAPACITY 50
typedef struct dictionary_item {
char* ptr_key;
void* ptr_value;
} dict_item;
typedef struct dictionary {
dict_item* items;
uint16_t size, max_capacity;
} Dict;
Dict* dict_new() {
Dict *my_dict = calloc(1, sizeof *my_dict);
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof my_dict->items);
my_dict->size = 0;
my_dict->max_capacity = DICT_INITIAL_CAPACITY;
for (int j = 0; j < my_dict->max_capacity; j++) {
int key_null = 1;
int value_null = 1;
if ((my_dict->items + j)->ptr_key != NULL)
key_null = 0;
if ((my_dict->items + j)->ptr_value != NULL)
value_null = 0;
if ((my_dict->items + j)->ptr_key != NULL || (my_dict->items + j)->ptr_value != NULL)
printf("item %d, key_null %d, value_null %d\n", j, key_null, value_null);
}
return my_dict;
}
int main(int argc, char** argv) {
Dict* dict = dict_new();
}
However it produces the output:
item 25, key_null 1, value_null 0
The only non-zero item is always the one at DICT_INITIAL_CAPACITY / 2. I've tried also using memset to put all the block to zero and the result is the same. If I put the memory to zero explicitly using:
for (int j = 0; j < my_dict->max_capacity; j++){
(my_dict->items + j)->ptr_key = 0;
(my_dict->items + j)->ptr_value = 0;
}
Then I get the desired behavior. But I do not understand why it does not work using calloc. What am I doing wrong?
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof my_dict->items);
Should be
my_dict->items = calloc(DICT_INITIAL_CAPACITY, sizeof *my_dict->items);
Also note that, in general, calloc may not set pointers to null (although it does on all modern systems that I know of). It would be safer to explicitly initialize any pointers that are meant to be null.
Having said that, you seem to be storing a size variable to indicate the size of the dictionary, so you could avoid this problem entirely by not reading entries beyond the current size; and when you do increase size then initialize the entries you have just added.
I need to have buffers that I will use it in multiple different types of threads. So the array needs to be global.
Buffer size and number of buffers are given as input to the program.
As an alternative I could implement linked list maybe.
What is the best way to implement such buffers? Can you provide a sample?
Any help is appreciated!
I don't understand what do you mean by "without knowing length", if you pass size of each buffer and number of buffers as input parameters then you know every required length.
Maybe this is not the best, but that would be my way.
First declare global buffer and threads.
static void ** buffer;
pthread_t tid[2];
Here is described how the threads will work. First buffer will assign with data first two sub-buffers. Second will do the same with the other two.
void *assignBuffer(void *threadid) {
pthread_t id = pthread_self();
if (pthread_equal(id, tid[0])) {
strcpy(buffer[0], "foo");
strcpy(buffer[1], "bar");
} else {
strcpy(buffer[2], "oof");
strcpy(buffer[3], "rab");
}
return NULL;
}
Converting program args from string to integer.
Here we assign buffer with arrays of unknown type.
Here we assign each buffer with his size in bytes.
Finally we create working threads. The important thing is that they
will run simultaneously.
Waiting until all threads done their job.
Simple print buffer contents.
Ok, here is the code.
int main(int argc, char **argv) {
//1
int bufferSize = atoi(argv[1]);
int buffersAmount = atoi(argv[2]);
//2
buffer = malloc(sizeof(void *)*buffersAmount);
//3
int i;
for (i = 0; i < buffersAmount; ++i) {
buffer[i] = malloc(bufferSize);
}
//4
i = 0;
while (i < 2) {
pthread_create(&tid[i], NULL, &assignBuffer, NULL);
++i;
}
//5
for (i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
//6
for (i = 0; i < 4; ++i) {
printf("%d %s\n", i, (char*)buffer[i]);
}
for (i = 0; i < buffersAmount; ++i) {
free(buffer[i]);
}
return 0;
}
Feel free to ask if you don't understand something, also sorry for my english it is not my native language.
I have a dynamic 2d array inside this struct:
struct mystruct{
int mySize;
int **networkRep;
};
In my code block I use it as follows:
struct myStruct astruct[100];
astruct[0].networkRep = declareMatrix(astruct[0].networkRep, 200, 200);
// do stuff...
int i;
for(i=0; i<100; i++)
freeMatrix(astruct[i].networkRep, 200);
This is how I declare the 2d array:
int** declareMatrix(int **mymatrix, int rows, int columns)
{
mymatrix = (int**) malloc(rows*sizeof(int*));
if (mymatrix==NULL)
printf("Error allocating memory!\n");
int i,j;
for (i = 0; i < rows; i++)
mymatrix[i] = (int*) malloc(columns*sizeof(int));
for(i=0; i<rows; i++){
for(j=0; j<columns; j++){
mymatrix[i][j] = 0;
}
}
return mymatrix;
}
And this is how I free the 2d array:
void freeMatrix(int **matrix, int rows)
{
int i;
for (i = 0; i < rows; i++){
free(matrix[i]);
}
free(matrix);
matrix = NULL;
}
The strange behvior that I'm seeing is that when I compile and run my program everything looks OK. But when I pipe the stdout to a txt file, I'm getting a seg fault. However, the seg fault doesn't occur if I comment out the loop containing the "freeMatrix" call. What am I doing wrong?
I don't see any problem in free code, except, freeMatrix get called for 100 times whereas your allocation is just 1.
So, either you allocate as below:
for(int i=0; i<100; i++) //Notice looping over 100 elements.
astruct[i].networkRep = declareMatrix(astruct[i].networkRep, 200, 200);
Or, free for only 0th element which you have allocated in your original code.
freeMatrix(astruct[0].networkRep, 200);
On sidenote: Initialize your astruct array.
mystruct astruct[100] = {};
struct myStruct astruct[100];
astruct[0].networkRep = declareMatrix(astruct[0].networkRep, 200, 200);
// do stuff...
int i;
for(i=0; i<100; i++)
freeMatrix(astruct[i].networkRep, 200);
You allocated one astruct but free 100 of them; that will crash if any of the 99 extra ones isn't NULL, which probably happens when you do your redirection. (Since astruct is on the stack, it will contain whatever was left there.)
Other issues:
You're using numeric literals rather than manifest constants ... define NUMROWS and NUMCOLS and use them consistently.
Get rid of the first parameter to declareMatrix ... you pass a value but never use it.
In freeMatrix,
matrix = NULL;
does nothing. With optimization turned on, the compiler won't even generate any code.
if (mymatrix==NULL)
printf("Error allocating memory!\n");
You should exit(1) upon error, otherwise your program will crash and you may not even see the error message because a) stdout is buffered and b) you're redirecting it to a file. Which is also a reason to write error messages to stderr, not stdout.
astruct[0].networkRep = declareMatrix(astruct[0].networkRep, 200, 200);
your not passing the address of the pointer. It just passes the value in the memory to the function which is unncessary.
And your only initializing first variable of struct but while you are trying to free the memory you are unallocating memory which is not yet allocated (astruct[1] and so on till 100 ).
When you use a malloc , it actually allocates a bit more memory than you you specified. extra memory is used to store information such as the size of block, and a link to the next free/used block and sometimes some guard data that helps the system to detect if you write past the end of your allocated block.
If you pass in a different address, it will access memory that contains garbage, and hence its behaviour is undefined (but most frequently will result in a crash)
To index and count an unsigned integer type is enough. size_tis the type of choice for this as it is guaranteed to be larger enough to address/index every byte of memory/array's element on the target machine.
struct mystruct
{
size_t mySize;
int ** networkRep;
};
Always properly initialise variables:
struct myStruct astruct[100] = {0};
Several issues with the allocator:
Give it a chance to returned specific error codes. This typically is done by setting using the function returned value to to so.
Use size_t for counters and indicies and sizes ("rows", "columns")(for why please see above).
Do proper error checking.
Clean up in case an error occurs during work.
do not cast the value returned by malloc(), as in C it's not necessary, not recommended
Use perror() to log error, as it gets the most from the OS about the as possibe.
A possible to do this:
int declareMatrix(int *** pmymatrix, size_t rows, size_t columns)
{
int result = 0; /* Be optimistc. */
assert(NULL != pmatrix);
*pmymatrix = malloc(rows * sizeof(**pmymatrix));
if (NULL == *pmymatrix)
{
perror("malloc() failed");
result = -1;
goto lblExit;
}
{
size_t i, j;
for (i = 0; i < rows; i++)
{
(*pmymatrix)[i] = malloc(columns * sizeof(***pmymatrix));
if (NULL == (*pmymatrix)[i])
{
perror("malloc() failed");
freeMatrix(pmymatrix); /* Clean up. */
result = -1;
goto lblExit;
}
for(i = 0; i < rows; ++i)
{
for(j = 0; j < columns; ++j)
{
(*pmymatrix)[i][j] = 0;
}
}
}
}
lblExit:
return 0;
}
Two issues for the de-allocator:
Mark it's work as done be properly de-initilaising the pointer.
Perform validation of input prior to acting on it.
A possible to do this:
void freeMatrix(int *** pmatrix, size_t rows)
{
if (NULL != pmatrix)
{
if (NULL != *pmatrix)
{
size_t i;
for (i = 0; i < rows; ++i)
{
free((*pmatrix)[i]);
}
}
free(*pmatrix);
*pmatrix = NULL;
}
}
Then use the stuff like this:
struct myStruct astruct[100] = {0};
...
int result = declareMatrix(&astruct[0].networkRep, 200, 200);
if (0 != result)
{
fprintf("declareMatrix() failed.\n");
}
else
{
// Note: Arriving here has only the 1st element of astruct initialised! */
// do stuff...
}
{
size_t i;
for(i = 0; i < 100; ++i)
{
freeMatrix(&astruct[i].networkRep, 200);
}
}
UPDATE:
I've changed the static array for a dynamic, but I still get the segment violation error, although eclipse says:
*** glibc detected *** (path to file) double free or corruption (!prev): 0x00000000004093d0 ***
StructHashTable is a typedef...
int main() {
...
StructHashTable *B0 = (StructHashTable *) malloc(N_ELEMS*sizeof(StructHashTable));
...
}
void resizeHash(StructHashTable *hash) {
int size = currentElements + N_ELEMS;
StructHashTable newHash[size];
int i;
for (i = 0; i < size; i++) newHash[i].key = FREE;
for (i = 0; i < currentElements; i++) insertHash(newHash, hash[i]);
currentElements = size;
hash = (StructHashTable *) realloc(hash, size*sizeof(StructHashTable));
if (hash != NULL) {
for (i = 0; i < size; i++) hash[i] = newHash[i];
}
}
What's wrong now? Am I using in a bad way realloc? or what? C is driving me crazy...
OLD:
I'm working in university homework and I need to resize an static array in C, it has to be static, the debbugger says segment violation...
I have a main function that declares the array...
// File: main.c
int main() {
...
StructHashTable hash[N_ELEMS];
...
}
At some point on runtime I need more elements than N_ELEMS and I've written a function to do it in HashTable.c, that's the method:
// File: HashTable.c
#define N_ELEMS 32
int currentElements = N_ELEMS
void resizeHashTable(StructHashTable *hash) {
int size = currentElements + N_ELEMS;
StructHashTable newHash[size];
int i;
// Inicialize newHash
for (i = 0; i < size; i++) newHash[i].key = FREE;
// Insert old hash elements to the new table...
for (i = 0; i < currentElements; i++) {
insertHash(newHash, hash[i]);
}
currentElements = size;
// I've tried making hash null with no luck...
//hash = NULL;
//free(hash);
// HERE'S THE ERROR...
hash = newHash;
// I've tried *hash = *newHash with the same result...
}
Can someone tell me how to do what I'm trying to do?
Thanks.
You are getting error because you are trying to modify the l-value for a statically allocated array 'hash'.
Whenever you define an array (as in main)
StructHashTable hash[N_ELEMS];
sizeof(StructHashTable)*N_ELEMS bytes of memory is allocated for hash, and hash points to the first byte. Such an allocation is called static allocation and you cannot make hash point to some other memory allocation. It will give error as you specified, because the l-value i.e left hand side value cannot be modified. Neither you can free the memory assigned to hash. Memory assigned to hash will be freed only when main will terminate.
// HERE'S THE ERROR...
hash = newHash;
I suggest you to use dynamic memory allocation for hash in main, if you wish to resize hash during run time.
int main() {
...
//Initial hash table creation
StructHashTable *B0 = (StructHashTable *) malloc(N_ELEMS*sizeof(StructHashTable));
...
...
//Do something
...
...
//hash table full. So resize hash table. This function call need not be inside main. Just for illustration purpose I am doing it here.
B0 = resizeHash(B0);
...
}
And here's your modified resizeHash function.
StructHashTable* resizeHash(StructHashTable *oldHash) {
int size = currentElements + N_ELEMS;
int i;
//Allocate memory for newHash with larger number of elements.
StructHashTable *newHash = (StructHashTable*) malloc(size * sizeof(StructHashTable));
if (newHash != NULL) {
for (i = 0; i < currentElements; i++) {
// Copy one by one oldHash table elements into newhash table
//Something like below, or whatever you have been doing before to copy.
newHash[i] = oldHash[i];
}
}
//Free memory occupied by oldHash
free(oldHash);
//Set new value for currentElements
currentElements = size;
//return the newHash address to calling function.
return (newHash);
}