Passing a string to a function with pointer / C - c

I want to pass this in my function, but something is going wrong
FILE *f = fopen("out.bmp", "rb");
int countBit = 0;
int size = 0;
char* type;
for (int i = 0; i < 54; i++)
fgetc(f);
printf("/* count bit to pixel */\n");
scanf("%d", &countBit);
size=DecodeInformationSize(f, countBit);
type=DecodeInformationType(f, countBit);
DecodeMessage(f,countBit,size,type);
before entering the function type is txt
but after :
void DecodeMessage(FILE *f, int countBit, int size, char* type)
{
char messageSize[8];
char nameOut[15] = "outMessage.";
strcat(nameOut, type);
char* message = (char*)malloc(size * 8);
please explain problem

To be absolutely sure we need to know what DecodeInformationType(f, countBit); does.
However, it seems it uses some data on the stack. Once it returns, this information may only be available for a few instructions. So your debugger shows that the call to DecodeMessage, type points to a valid string, but once you enter DecodeMessage, the stack is overwritten with the variables of DecodeMessage, in particular with char nameOut[15] = "outMessage.";
To solve this, make sure that DecodeInformationType returns a pointer to memory that is not on the stack (not an automatic variable) of DecodeInformationType. That could be memory allocated with malloc or a constant string.

Related

How to read memory zone in C

I'm working on a project and I have a list of functions to use.
I use the provided DLL.
I have the function's prototypes in the file "list.h".
This file is also provided to me
list.h
typedef unsigned short (__stdcall * ReadConfig)
(void * * pDataOut,
size_t * pSizeDataOut);
I wrote this main.c
int main (int nbArg, char** listeArg)
{
// Initialization
unsigned short outputFunction;
void * pointerMemoryZone = NULL;
size_t sizeMemoryZone = NULL;
// Load DLL
HMODULE dllLoadOuput= LoadLibrary("dllFile");
// Alias Creation
typedef unsigned short(*A_ReadConfig) (void * *, size_t *);
// Get Pointer on Function
A_ReadConfig ptrReadConfiguration = (A_ReadConfig)GetProcAddress(dllLoadOuput, "ReadConfig");
// Launch of the function
outputFunction = ptrReadConfiguration(&pointerMemoryZone, &sizeMemoryZone);
// Display
printf("\n\nSize Read Config : %ld\n\n", sizeMemoryZone);
// Unload DLL
FreeLibrary(dllLoadOuput);
return 0;
}
This program works and I get the size of the memory area fine.
But my program, my variables are they correctly declared and used...?
And how can I read the data contained in the memory area...?
Below is a diagram provided in the documentation :
Presumming outputFunction indicates success, the pointer pointerMemoryZone should contain sizeMemoryZone bytes of data.
How you access the data depends on the format (e.g. text/json/xml string).
A sample loop to display the data in ascii and hex:
for(int i=0; i<sizeMemoryZone; i++) {
char c = ((char*) pointerMemoryZone)[i];
printf("%c{%x} ", c, c);
}
I answer to my question. I find a solution.
I have to read datas byte by byte.
So I create a caracter pointer on "pointerMemoryZone" (wich contains adress of datas) by forcing the pointer type to character (because 1 byte)
And I make a loop in which I loop through the addresses one by one (along the length of the data)
Below the code for the loop
//...
//...
//...
// Launch of the function
outputFunction = ptrReadConfiguration(&pointerMemoryZone, &sizeMemoryZone);
// Creation of Pointer
char *pointerOnPointerMemoryZone = NULL;
// Begin Loop
for (int i = 0; i < sizeMemoryZone; i++)
{
// Association Pointer to Adress (+0, +1, +2, etc..)
pointerOnPointerMemoryZone = (char*)pointerMemoryZone + i;
printf("\n%d\t\t%d\t\t%c",i, *pointerOnPointerMemoryZone, *pointerOnPointerMemoryZone);
}
// End Loop
//...
//...
//...

ERROR "realloc(): invalid next size" when allocating memory to const char*** variable

I have a function
populateAvailableExtensions(const char** gAvailableExtensions[], int gCounter)
which take a pointer to an array of strings and the number of elements in the array as parameters.
I allocate initial memory to that array using malloc(0). Specs say that it will either return a null pointer or a unique pointer that can be passed to free().
int currentAvailableExtensionCount = gCounter;
This variable will store number of string in gAvailableExtensions.
Inside this for loop
for (int i = 0; i < availableExtensionCount; ++i)
I have this piece of code
size_t sizeOfAvailableExtensionName =
sizeof(availableExtensionProperties[i].name);
reallocStatus = realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
&availableExtensionProperties[i].name,
sizeOfAvailableExtensionName);
++currentAvailableExtensionCount;
where
availableExtensionProperties[i].name
returns a string.
This is how that struct is defined
typedef struct Stuff {
char name[MAX_POSSIBLE_NAME];
...
...
} Stuff;
realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
should add memory of size sizeOfAvailableExtensionName to *gAvailableExtensions de-referenced array.
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
&availableExtensionProperties[i].name,
sizeOfAvailableExtensionName);
should copy the string (this sizeOfAvailableExtensionName much memory) from
&availableExtensionPropterties[i].name
address to
&(*gAvailableExtensions)[currentAvailableExtensionCount]
address.
But I don't think the code does what I think it should because I'm getting this error
realloc(): invalid next size
Aborted
(core dumped) ./Executable
EDIT: Full code
uint32_t populateAvailableExtensions(const char** gAvailableExtensions[], int gCounter) {
int currentAvailableExtensionCount = gCounter;
void* reallocStatus;
uint32_t availableExtensionCount = 0;
vkEnumerateInstanceExtensionProperties(
VK_NULL_HANDLE, &availableExtensionCount, VK_NULL_HANDLE);
VkExtensionProperties availableExtensionProperties[availableExtensionCount];
vkEnumerateInstanceExtensionProperties(
VK_NULL_HANDLE, &availableExtensionCount, availableExtensionProperties);
for (int i = 0; i < availableExtensionCount; ++i) {
size_t sizeOfAvailableExtensionName =
sizeof(availableExtensionProperties[i].extensionName);
reallocStatus = realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
availableExtensionProperties[i].extensionName,
sizeOfAvailableExtensionName);
++currentAvailableExtensionCount;
}
return currentAvailableExtensionCount;
}
This is how an external function calls on that one,
uint32_t availableExtensionCount = 0;
availableExtensions = malloc(0);
availableExtensionCount = populateAvailableExtensions(&availableExtensions);
and
const char** availableExtensions;
is declared in header file.
EDIT 2: Updated the code, now gCounter holds the number of elements in gAvailableExtensions
This loop is totally messy:
for (int i = 0; i < availableExtensionCount; ++i) {
size_t sizeOfAvailableExtensionName =
sizeof(availableExtensionProperties[i].extensionName);
reallocStatus = realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
availableExtensionProperties[i].extensionName,
sizeOfAvailableExtensionName);
++currentAvailableExtensionCount;
}
I assume the only lines that does what you expect them to do, are the lines for (int i = 0; i < availableExtensionCount; ++i) and ++currentAvailableExtensionCount;
First, the typical way to use realloc is like this:
foo *new_p = realloc(p, new_size);
if (!new_p)
handle_error();
else
p = new_p;
The point is that realloc will not update the value of p if a reallocation happens. It is your duty to update 'p'. In your case you never update *gAvailableExtensions. I also suspect that you don't calculate sizeOfAvailableExtensionCount correctly. The operator sizeof always return a compile time constant, so the realloc doesn't actuall make any sense.
The memcpy doesn't actally make any sense either, since you are copying the string into the memory of a pointer array (probably with an additional buffer overflow).
You said that *gAvailableExtensions is a pointer to an array of pointers to strings.
That means that you have to realloc the buffer to hold the correct number of pointers, and malloc memory for each string you want to store.
For this example, I assume that .extensionName is of type char * or char[XXX]:
// Calculate new size of pointer array
// TODO: Check for overflow
size_t new_array_size =
(currentAvailableExtensionCount + availableExtensionCount) * sizeof(*gAvailableExtensions);
char **tmp_ptr = realloc(*gAvailableExtensions, new_array_size);
if (!tmp_ptr)
{
//TODO: Handle error;
return currentAvailableExtensionCount;
}
*gAvailableExtensions = tmp_ptr;
// Add strings to array
for (int i = 0; i < availableExtensionCount; ++i)
{
size_t length = strlen(availableExtensionProperties[i].extensionName);
// Allocate space for new string
char *new_s = malloc(length + 1);
if (!new_s)
{
//TODO: Handle error;
return currentAvailableExtensionCount;
}
// Copy string
memcpy (new_s, availableExtensionProperties[i].extensionName, length + 1);
// Insert string in array
(*gAvailableExtensions)[currentAvailableExtensionCount] = new_s;
++currentAvailableExtensionCount;
}
If you can guarantee that the lifetime of availableExtensionProperties[i].extensionName is longer than *gAvailableExtensions, you can simplify this a little bit by dropping malloc and memcpy in the loop, and do:
char *new_s = availableExtensionProperties[i].extensionName;
(*gAvailableExtensions)[currentAvailableExtensionCount] = new_s;
Some harsh words at the end: It seems like you have the "Infinite number of Monkeys" approach to programming, just hitting the keyboard until it works.
Such programs will just only give the illusion of working. They will break in spectacular ways sooner or later.
Programming is not a guessing game. You have to understand every piece of code you write before you move to the next one.
int currentAvailableExtensionCount =
sizeof(*gAvailableExtensions) / sizeof(**gAvailableExtensions) - 1;
is just a obfuscated way of saying
int currentAvailableExtensionCount = 0;
I stopped reading after that, because i assume that is not what you intend to write.
Pointers in c doesn't know how many elements there are in the sequence they are pointing at. They only know the size of a single element.
In your case *gAvailableExtensions is of type of char ** and **gAvailableExtensions is of type char *. Both are pointers and have the same size on a typical desktop system. So on a 64 bit desktop system the expression turns into
8/8 - 1, which equals zero.
Unless you fix this bug, or clarify that you actually want the value to always be zero, the rest of the code does not make any sense.

Releasing pointer memory aswell as pointer itself

A "Deeltal" keeps track of how many dividers an integer has (count) and keeps them in an array (dividers).
Examples:
value = 8 -> count = 3 and dividers = {1,2,4}
value = 10, count = 3, dividers = {1,2,5}
Hope everything is clear, take a look at the following code:
typedef struct{
int value;
int count;
int* dividers;
} Deeltal;
void free_dividers(Deeltal *g){ /*Deletes the int* dividers of a given Deeltal*/
free (g - > dividers);
}
/* the following two functions have the same purpose: deleting the content of a
given amount of "Deeltal" AND deleting the pointer to it aswell*/
void free_amountOfdeeltal(Deeltal *d, int amount){
int i;
for (i = 0; i < amount; i++){
free_dividers(&d[i]);
}
free(d);
}
void free_amountOfdeeltalVersion2(Deeltal **g, int amount){
int i;
for(i = 0; i < amount; i++){
free_dividers(&(*g)[i]);
}
free(*g);
}
If my main looked something like this
int main(void){
/*EDIT 3/11/2017: forgot to allocate memory for *d and initializing g.
Thanks for pointing this out*/
Deeltal g = 0;
g.value = 6; g.count = 3; g.dividers = {1,2,3};
Deeltal *d = malloc(sizeof(Deeltal));
d->value = 6; d->count = 3; d->dividers = {1,2,3};
free_amountOfdeeltal(&g);
free_amountOfdeeltalVersion2(&d);
}
What is the difference between free_amountOfdeeltal and free_amountOfdeeltalVersion2?
Both should do the same thing: releasing the memory of a Deeltal and also deleting the pointer pointing to that memory.
On a sidenote:
How do you delete the memory as well as the pointer?
Not withstanding calling this function with invalid data as pointed out by others .. I'll attempt to answer the question I think you are asking.
On a sidenote: How do you delete the memory as well as the pointer?
You can't really "delete the pointer" in this context as a pointer is simply a variable that is assigned an address. You delete memory that was allocated to you by passing free a pointer to the memory. Note that free does not modify the value of the pointer at all. (It can't because the pointer is passed by value.) After the call to free the pointer still points to the same memory address.
If what you mean is "how can I assign a meaningful value to the pointer to identify that its memory has already been deleted," then you can use the second form of your function:
void free_amountOfdeeltalVersion2(Deeltal **g, int amount);
and set *g to NULL before returning. You can then use this information than the pointer is NULL to identify the memory has already been deleted.
You didn't allocate any memory for d so your pointer doesn't point to any structure. Therefor, you can't access its properties or free its memory because you didn't reserve it in the first place. There's no way this code could come remotely close to compiling.
First of all you should be allocating memory for a "Deeltal" structure like this:
Deeltal *d = malloc(sizeof(Deeltal));
I recommend you go back and relearn how pointers work, as you're doing some really weird stuff there.

How to return an array in without storing globally?

I have utitlity function which gives me a char buffer of individual bytes, when I provide it with a structure.
unsigned char complete[16] = { 0 };
char* construct_complete_array(socketType* m)
{
unsigned char *temp = (unsigned char*) m;
size_t j;
for (j = 0; j < sizeof(*m); j++)
{
complete[j] = *(temp);
printf("%.2x ", *(temp));
*temp++;
}
return complete;
}
int diff_bit_calc(socketType* datanode, socketType* knode)
{
char* result = construct_complete_array(datanode);
size_t j;
printf("\nPrinting result: \n");
for (j = 0; j < sizeof(*datanode); j++)
{
printf("%.2x ", *(result));
*result++;
}
}
I want it to be a generic function which when provided with a structure will return me a char buffer of the structure.
I might have another invocation like
char* result1 = construct_complete_array(knode);
(I don't think having complete[16] buffer as global a good idea. Having it local and returning it is still a worser idea. )
In general, you can't do that without dynamically allocating memory. Most people get around it by declaring the buffer in the calling function and passing that buffer to a function, which will then fill in the passed buffer.
In your specific case, I'm not so sure a function is necessary; it's rather short to do it inline, e.g.:
/* to get the bytes representing `something' into a char array */
char something_chars[sizeof(something)];
memcpy(something_chars, &something, sizeof(something));
As for as I know, there are two ways to do that.
Since the return value of the function is a pointer, so you must make sure that the memory you store result won't be destroyed. Other than using global variable, you can use dynamic allocating memory(like icktoofay said) or static keyword
(like Tay Wee Wen said).
When using dynamic allocating memory, the user of this function should remember to free() outside the function.
When using static keyword inside the block, there is a problem of overriding. If you call the function several times, only the last return value was kept.
By the way, *temp++; is a little strange, why not use temp++; instead.
Declare the array static inside the function.
char* construct_complete_array(socketType* m){
static unsigned char complete[16]= {0};
unsigned char *temp = (unsigned char*)m;
size_t j;
for (j = 0;j<sizeof(*m);j++){
complete[j] = *(temp);
printf("%.2x ", *(temp));
*temp++;
}
return complete;
}
You'd have to change your interface a bit:
char* construct_complete_array(socketType* m, char temp[]);
then on the calling side you can use a compound literal to provide temp
char* result = construct_complete_array(datanode, (char[sizeof *datanode]){ 0 });
If you have to repeat that in several places you could put that into a macro
#define CONSTRUCT_ARRAY(X) construct_complete_array((X), (char[sizeof *(X)]){ 0 })
so then again your call side looks almost as you had it before
char* result = CONSTRUCT_ARRAY(datanode);
For this to work you just have to have in mind that the value in result points to local data with the same life time as result itself.

2D arrays passed through functions in c

I'm having a problem with my program. I need my program to read from a text file, the first consists of the dimensions of the 2d array the rest is the contents of the array. I have coded the readWord function which reads from textfiles and it works but when i do anything on the main function with the array it crashes. Please could you help.
int main()
{
int num_it, cols, rows;
char** myworld;
num_it = readWorld(myworld,&cols, &rows);
myworld[1][2]='x';/*it crashes when i make this statement*/
}
int readWorld(char** world, int* width,int* height)
{
int result=0,i,cols=0,rows=0;
char buff[25];
FILE* file = fopen ("world.txt", "r");
fscanf(file, "%d %d %d\n", width, height, &result);
/*Dynamic allocation*/
world = (char**)malloc(*(height)* sizeof(char*));
for(i=0;i<*height;i++)
{
world[i] = (char*)malloc(*width*sizeof(char));
}
/*store data in array*/
while(fgets(buff, sizeof buff, file) != NULL)
{
if (strlen(buff) >1){
for(cols=0; cols<=(strlen(buff)); ++cols)
{
world[rows][cols] = buff[cols];
}
++rows;
}
}
fclose(file);
return result;
}
You need to allocate the memory for myworld in the actual caller!
What's happening here is that you are passing the pointer by value to the function.
The pointer value is changed by the function but that's not going to adjust the one in the caller.
Two options: use a triple indirection (ie pass a pointer to the the pointer) or allocate in the main sub. I prefer the latter, mainly because you can control the memory deallocation in a more symmetrical manner; even if you fixed this problem your code still has the memory leak.
What you're experiencing is undefined behaviour as you are attempting to access memory your program does not own.
Your myworld variable in main is never initialized and points to junk, so when you try to access it bad things happen. Think about why: you are passing a copy of the variable to readWorld. You correctly allocate memory inside there, and make the copy point to it, but the original pointer (in main) still points to whatever random location it pointed to before.
If you want the memory for it to be allocated inside the readWorld function and made accessible via the myworld variable in main then you must pass a pointer to myworld to readWorld; in other words, you must pass a triple pointer.
Try this:
int readWorld(char*** world, int* width,int* height)
{
char **tempworld = malloc(...);
// do whatever
*world = tempworld;
return result;
}
int main()
{
char **myworld = NULL;
readWorld(&myworld, ...);
return 0;
}

Resources