I'm trying to allocate memory in a function in C, then process the memory in main() and other functions. I have Visual Studio 2022 running on a Windows 10 platform. I found relevant information at the link C Programming: malloc() inside another function but could not get anything to work correctly.
Basically what I'm trying to do is to read a BMP image file into two buffers, one holding the header which is fixed, and one holding the pixel data which I want to manipulate. After the pixel data have been manipulated, I want to write both buffers to a new output file.
I have the following setup: In the header a couple of defines are:
#define FNAME_LEN 31 // Length of filename
#define IMG_HEADR 54 // Length of image header
In the main function I want to copy the header into buf1, which will not be changed, and the pixel data in buf2 which will be modified. The code is as follows:
printf("Type the input filename:");
char imgFn[FNAME_LEN] = { 0 };
scanf_s("%s",imgFn, FNAME_LEN);
BYTE **buf1, **buf2;
buf1 = buf2 = NULL; // Is this necessary?
int numBytes1 = readBinDiv(imgFn, FNAME_LEN, IMG_HEADER, &buf1, &buf2);
printf("%s%d\n", "numBytes1: ", numBytes1);
if (buf1 == NULL) printf("buf1 is NULL\n"); // Debug
if (buf2 == NULL) printf("buf2 is NULL\n"); // Debug
// Code for processing buf2 will be added here.
printf("Type the output image filename:");
char imgFnOut[FNAME_LEN] = { 0 };
scanf_s("%s", imgFnOut, FNAME_LEN);
int numBytes2 = writeBinCom(imgFnOut, FNAME_LEN, IMG_HEADER, numBytes1 - IMG_HEADER, buf1, buf2);
printf("%s%d\n", "numBytes2: ", numBytes2);
if (buf1 == NULL) printf("buf1 is NULL\n"); // Debug
if (buf2 == NULL) printf("buf2 is NULL\n"); // Debug
After each of these functions are invoked, I test if the buffers are NULL for debugging.
In the function that reads from a binary file, it first open the file, reads the data into buf1 for the header and buf2 for the pixel data, then closes the file. I need this data to be available from outside the function. The code is a follows:
int readBinDiv(char* fn, int fl, int buf1Len, BYTE** buf1, BYTE** buf2) {
if (buf1 != NULL || buf2 != NULL) return -1;
FILE* tempFp = NULL;
if (fopen_s(fp, fn, "rb") != 0) return -2;
fseek(tempFp, 0, SEEK_END);
size_t imgLen = ftell(tempFp);
if (imgLen <= buf1Len) { // File length is not larger than the header.
fclose(tempFp);
return -3;
}
rewind(tempFp);
// Allocate buffers.
*buf1 = (BYTE*)malloc(buf1Len); // C6011 Dereferencing NULL pointer buf1.
*buf2 = (BYTE*)malloc(imgLen - buf1Len); // Same as above
if (buf1 == NULL || buf2 == NULL) { // Unable to allocate a buffer.
fclose(tempFp);
return -4;
}
// Read the file into the two buffers, the close the file.
fread(&buf1, 1, buf1Len, tempFp);
fseek(tempFp, buf1Len, SEEK_SET);
size_t imgRest = fread(&buf2, 1, imgLen - buf1Len, tempFp);
fclose(tempFp);
if (imgRest != (imgLen - buf1Len)) return -(int)imgRest;
return (int)imgLen;
}
If successful it returns a positive value for the number of bytes read, otherwise a negative value is returned indicating an error.
In the function that writes to a binary file, it does the reverse. It opens a new file for writing, writes buf1 with the header to the beginning of the file, buf2 for the pixel data, then closes the file and frees the buffers. The code is as follows:
int writeBinCom(char* fn, int fl, int buf1Len, int buf2Len, BYTE* buf1, BYTE* buf2) {
if (buf1 == NULL || buf2 == NULL) return -1;
FILE* tempFp = NULL;
// Open output file
if (fopen_s(fp, fn, "wb") != 0) return -2;
size_t len1 = fwrite(buf1, 1, buf1Len, tempFp);
fseek(tempFp, buf1Len, SEEK_SET);
size_t len2 = fwrite(buf2, 1, buf2Len, tempFp);
fclose(tempFp);
free(buf1);
free(buf2);
buf1 = buf2 = NULL; // Reset to NULL - is this needed?
if (len1 != buf1Len || len2 != buf2Len) return -3;
return len1 + len2;
}
As before a positive return value is the number of bytes written to the file if successful, and should be the same as the number of bytes read.
In both functions f_open() is in fact not invoked directly, but from other function to perform various checks that the file can be read from or written to. This part of the code works and is omitted here.
All attempts to get this to work fail, either the compiler complains, I receive messages such as the warning C6011 by the IDE as above, or NULL or a negative value is returned by the first function. In some cases the first function appears to run correctly returning a valid number of bytes read from the file, but the buffers are NULL on return and the write function cannot work.
I would be very grateful in getting this matter resolved.