Dynamically reallocating an array of structs in C [closed] - c

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
A part of my code will read in an unknown number of lines from a text file, parse that line into a structure (tempSomeStruct), resize the SomeStruct_Array, and then add that tempSomeStruct into the newly opened spot in memory.
However after a few times through the while loop, my program stops and says
myApplication.exe has triggered a breakpoint.
I did not set a breakpoint, and doing some digging, it LOOKS like the breakpoint is due to heap corruption from my call to realloc. I am pretty new to dynamic allocation, so while I have searched and found a few possible causes, so far no fixes have worked.
How am I corrupting the heap in this situation, and what do I do differently to avoid doing so?
I have a function like this:
int growArray(SomeStruct **SomeStruct_Array,int currentSize, int numNewElements)
{
const int totalSize = currentSize + numNewElements;
SomeStruct *temp = (SomeStruct*)realloc(*SomeStruct_Array,(totalSize * sizeof(SomeStruct)));
if (temp == NULL)
{
printf("Cannot allocate more memory.\n");
return 0;
}
else
{
*SomeStruct_Array = temp;
}
return totalSize;
}
and it is called in elsewhere like this:
SomeStruct* SomeStruct_Array = (SomeStruct *) calloc(1,sizeof(SomeStruct));
int Error_Array_Size = 0;
if(SomeStruct_Array == NULL)
{
printf("Cannot allocate initial memory for data\n");
return;
}
while(fgets(line,sizeof(line), file) != NULL)
{
parseTextIntoSomeStruct(line, &tempSomeStruct);
SomeStruct_Array_Size = growArray(&SomeStruct_Array,SomeStruct_Array_Size,1);
if(SomeStruct_Array_Size > 0)
{
SomeStruct_Array[SomeStruct_Array_Size] = tempSomeStruct;
}
}

Your new array's size is SomeStruct_Array_Size, and you immediately write to SomeStruct_Array[SomeStruct_Array_Size] which is one past the end of the array! Remember, C arrays are zero-indexed.
Use
SomeStruct_Array[SomeStruct_Array_Size-1] = tempSomeStruct;
instead.

Related

memcpy extra starting characters [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm having some trouble using memcpy in that when the memcpy operation is performed I get:
"ÍÍWF03-021913.datýýýý««««««««þ"
when I should get:
"WF03-021913.datýýýý««««««««þ"
I don't know where these leading "ÍÍ" are coming from.
Code:
note: lpszFileName = "WF03-021913.dat"
typedef struct {
BYTE cbRequestType;
BYTE cbFileName;
char* szFileName;
} UFTP_GET_FILE_INFO_REQUEST;
BOOL Uftp_BuildFileInfoRequest(PUFTP_REQUEST request, LPCTSTR lpszFileName)
{
UFTP_GET_FILE_INFO_REQUEST *fileInfo;
int fileNameLen;
if (lpszFileName == NULL) {
ASSERT( 0 );
return FALSE;
}
fileNameLen = strlen( lpszFileName );
if (fileNameLen == 0)
return FALSE;
request->dwRequestSize = sizeof(UFTP_GET_FILE_INFO_REQUEST) -
sizeof(void*) + fileNameLen;
request->RequestBuffer = malloc( request->dwRequestSize );
if ( !request->RequestBuffer ) {
TRACE0("Failed to allocate RequestBuffer");
return FALSE;
}
fileInfo = (UFTP_GET_FILE_INFO_REQUEST*) request->RequestBuffer;
fileInfo->cbRequestType = UFTP_GET_FILE_INFO;
fileInfo->cbFileName = fileNameLen;
memcpy(&fileInfo->szFileName, lpszFileName, fileNameLen);
return TRUE;
}
I'm only guessing here, but my guess is that fileInfo->szFileName is a pointer. This means that &fileInfo->szFileName is a pointer to a pointer, so you copy to a complete other area of memory.
Also, you don't copy the terminating '\0' character needed. You need fileNameLen + 1 for that, both when allocating and when copying.
If you really want it all in contiguous memory, you should probably change the structure to end with a character-array of size zero (may not be supported by your compiler, then use an array of size 1) and use sizeof(UFTP_GET_FILE_INFO_REQUEST) + fileNameLen + 1 as the size to allocate. Then you can use the array as a normal string array.
And if you fix those problems, you have yet another problem: You don't initialize the pointer to point to allocated memory. This means it will point to some random memory.
All of these errors will lead to undefined behavior, and I would say you are lucky it didn't crash.

Error while trying to read n images using a loop? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
void main() {
int frame_number = 0;
do {
char *filename = "";
strcpy(filename, "frame_");
char *frame_id = "";
itoa(frame_number, frame_id, 10);
strcat(filename, frame_id);
strcat(filename, ".bmp");
FILE* f = fopen(filename, "rb");
if (!f) {
printf("Could not read!");
system("Pause");
}
else
printf("Read!");
fclose(f);
frame_number++;
} while (frame_number < 20);
}
Whenever I run this I get the error of access violation writing location !!!
There are around 40 images in the folder.
How to solve this ?
No memory has been allocated for filename and frame_id. Allocate memory before storing strings using malloc or calloc. Or just declare them as static arrays.
char filename[256]="";
char frame_id[256] = "";

Array of files and value assigning [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have 2 questions.
I want to create an array of files in C. But I'm not sure whether I have to malloc the size before or not.Can I just use FILE** files as an array or do I have to malloc them before. And if I have to make space, do I need to reserve 4 bytes (x86)?
I have the variable "char extra[8] = { 0xAE00AF00B000B100 };" and I want to assign it to the end of another char array[24]. Is there a faster way of doing that without having to type in every value by hand or using a for loop.
char extra[8] = { 0xAE00AF00B000B100 };
// index is a random place in the string
name[index] = '\0';
i = 0;
if (index > 16) {
for (i = 24-index; i < 8; i++) {
index++;
name[index] = extra[i];
}
}
else {
name[17] = 0xAE;
name[18] = 0x00;
name[19] = 0xAF;
name[20] = 0x00;
name[21] = 0xB0;
name[22] = 0x00;
name[23] = 0xB1;
name[24] = 0x00;
}
I need to add those extra bytes btw.
I want to create an array of files in C. But I'm not sure whether I
have to malloc the size before or not.Can I just use FILE** files as
an array or do I have to malloc them before. And if I have to make
space, do I need to reserve 4 bytes (x86)?
If you need to have an array of files, it is possible to use an array of pointers as follow:
#include <stdio.h>
FILE *array[NB_FILES];
Or you can do it dynamically if NB_FILES is only known at runtime.
#include <stdio.h>
#include <stdlib.h>
FILE **array = malloc(nb_files * sizeof *array);
I have the variable "char extra[8] = { 0xAE00AF00B000B100 };" and I want to assign it to the end of another char array[24]. Is there a faster way of doing that without having to type in every value by hand or using a for loop.
The standard C library provides the function memcpy, which is a builtin on many compiler (so it will be faster than a for loop).
#include <string.h>
char array[24];
char extra[8];
memcpy(array + sizeof array - sizeof extra - 1, extra, sizeof extra);

Creating 2D struct [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have aproblem with this code, it compiles ok. But it crashes imidiately after memory could not be written error.
Debugger says the problem is in the line *grid = (grid_t**)malloc(sizeof(grid_t)*GRID_HEIGHT); , i must be missing something obvious.
I'm trying to create a pointer to a 2D struct.
#define GRID_WIDTH 12
#define GRID_HEIGHT 22
typedef struct
{
int piece;
int edge;
}grid_t;
grid_t*** grid;
*grid = (grid_t**)malloc(sizeof(grid_t)*GRID_HEIGHT);
for(int i = 0 ; i < GRID_HEIGHT ; i++)
{
*grid[i] = (grid_t*)malloc(sizeof(grid_t)*GRID_WIDTH);
}
You dereference an unallocated pointer:
grid_t*** grid;
*grid = (grid_t**)malloc(sizeof(grid_t)*GRID_HEIGHT);
grid is not allocated when you do *grid, so it's undefined behavior.
If you want to dynamically allocate two-dimensional structs, you first need to allocate enough memory for pointers (grid_t*) in the first level:
grid_t** grid;
grid = malloc(sizeof(*grid) * GRID_HEIGHT);
Then you can allocate each element with a loop:
for(int i = 0 ; i < GRID_HEIGHT ; i++)
{
grid[i] = malloc(sizeof(**grid) * GRID_WIDTH);
// ...then you can do grid[i]->piece = 42; etc..
}
Now, from what I can see, you probably don't even need dynamic allocation. If you don't need malloc, don't use it, just use good ol' arrays instead:
grid_t grid[GRID_HEIGHT][GRID_WIDTH];

What var type you use on growing buffers [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
I need to read some bytes from a socket stream.
No i do a expanding buffer like this:
long curbufsize = 1024*24;
long expand = 1024*24;
void *buf = xmalloc(curbufsize);
void *buf_ptr_start = buf;
char mem[1024*24];
while (rc = my_read_from_stream(handle, mem, sizeof(men)) {
len = (int)buf-((int)buf_ptr_start+rc);
if(curbufsize < len) {
curbufsize+=expand;
xrealloc(buf_ptr_start, curbufsize);
}
memcpy(buf, mem, rc);
}
where should i use size_t and long/int? Should the buffersize be a size_t?
Should i better write for the new len calculation:
len = (size_t)buf-((size_t)buf_ptr_start+rc);
Any other optimization?
Thanks
Using int this way is incorrect since int may be smaller than the pointer size of your system and will thus lead to truncation. I'd use size_t to keep track of your current buffer size and there's no need for any pointer arithmetic.
The reallocation is also completely broken. Why are you calling xrealloc() and then ignoring the return value. That's like a leaking version of free()!
You could write it something like this:
size_t len = 0;
size_t size = 0;
size_t expand = 1024*24;
char *buf = NULL;
char *newbuf;
char mem[1024*24];
while (rc = my_read_from_stream(handle, mem, sizeof(men)) {
if (size < len+rc) {
while (size < len+rc)
{
size += expand;
}
newbuf = xrealloc(buf, size);
if (!newbuf)
{
free(buf);
return ERROR_MEMORY_ALLOCATION_FAILED;
}
buf = newbuf;
}
memcpy(buf+len, mem, rc);
len += rc;
}
You can look in the header file that declares xmalloc; the type of its parameter must be right there. Though by the look of your code you are not trying to write a portable application, so you probably don't need to worry about such choices.
Just fix the bugs.
Edit: seeing that you talk about optimization, take into account that int might be faster than size_t (most probably it isn't) - profile the two variants and choose the fastest (or acknowledge that they have the same efficiency).

Resources