I am trying to setup a local folder access from a c program by first initializing a string to the location the subsequently reading files from there. I'll also be required to write files in a similar manner eventually, but I am getting some strange bugs.
first the code:
resource_utils.h
static char* res_dir = NULL;
void clearnUpResourcePath(void);
char* getResource(char* filename);
char* readFile(char* file_path);
void writeFile(filename, File* file);
resource_utils.c
#include "resource_utils.h"
static char* getBasePath(void);
static void initResourcePath(void);
char* getResource(char* filename)
{
if(res_dir == NULL)
{
initResourcePath();
}
printf("res dir: %s || fn:%s\n",res_dir, filename);
char* str = (char*)malloc(sizeof(char) + strlen(res_dir) + strlen(filename));
memcpy(str, res_dir, strlen(res_dir)+1);
memcpy(str + strlen(res_dir), filename, strlen(filename));
str[(strlen(filename) + strlen(res_dir))] = '\0';
printf("resource filename:%s\n\n",str);
return str;
}
static void initResourcePath(void) {
char *base_path = getBasePath();
size_t len = strlen(base_path) + 22;
size_t i = 0;
size_t sz = 0;
char tmp[len];
while(base_path[i] != '\0')
{
if(base_path[i] == 'b' && base_path[i+1] == 'i' && base_path[i+2] == 'n')
{
sz = i;
}
tmp[i] = base_path[i];
i++;
}
char* b = strstr(tmp, "/bin");
memcpy(b, "/bin/resources/",15);
tmp[ sz + 14 ] = '\0';
res_dir = (char*)malloc(sizeof(char) * (sz + 4));
i = 0;
while(tmp[i] != '\0')
{
res_dir[i] = tmp[i];
i++;
}
res_dir[i] = '\0';
free(base_path);
}
void clearnUpResourcePath(void)
{
free(res_dir);
}
static char* getBasePath(void)
{
return "string to working directory"
}
char* readFile(char* file_path)
{
FILE* fp = fopen(file_path, "r");
if( fp == NULL )
{
perror("Error while opening the file.\n");
printf("failed to open file path:%s\n",file_path);
exit(EXIT_FAILURE);
}
size_t size = 1024;
char ch;
int index = 0;
char* line = (char*)malloc(sizeof(char) * size);
while( (ch = (char)fgetc(fp)) != EOF )
{
*(line+index) = ch;
++index;
if(index == size-1)
{
size = size * 2;
line = realloc(line, size);
printf("\nreallocing %zu\n",size);
}
line = realloc(line, (sizeof(char) * index) + 1);
*(line+index) = '\0';
}
//printf("sanity check\n\n%d\n\n",strlen(line));
//printf("final size: %lu for loading: %s\n",strlen(line), file_path);
fclose(fp);
return line;
}
This is basically suppose to setup this resource path once, keep it around for the lifetime of the program and free it before the program exits, but I get some strange results sometimes.
Take a look at this output
char* vshad = getResource("vert.shad");
char* fshad = getResource("frag.shad");
char* name = getResource("pal.ppm");
char* name1 = getResource("1234pal.ppm");
char* name2 = getResource("pal.ppm1234");
char* name3 = getResource("pal1.ppm");
char* name4 = getResource("pal.pp");
char* name5 = getResource("pal.ppdddddm");
char* name6 = getResource("pa");
res dir: /Users/username/DIRECTORY/project/build/bin/resources/ || fn:vert.shad
res dir len:48, filename len:9
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/vert.shad
res dir: /Users/username/DIRECTORY/project/build/bin/resources/ || fn:frag.shad
res dir len:48, filename len:9
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/frag.shad
res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal.ppm
res dir len:57, filename len:7
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.ppm
res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:1234pal.ppm
res dir len:57, filename len:11
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS1234pal.ppm
res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal.ppm1234
res dir len:57, filename len:11
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.ppm1234
res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal1.ppm
res dir len:57, filename len:8
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal1.ppm
res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal.pp
res dir len:57, filename len:6
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.pp
res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pal.ppdddddm
res dir len:57, filename len:12
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.ppdddddm
res dir: /Users/username/DIRECTORY/project/build/bin/resources/FACETKEYS || fn:pa
res dir len:57, filename len:2
resource filename:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpa
loaded name:/Users/username/DIRECTORY/project/build/bin/resources/FACETKEYSpal.ppm?
the first two calls load properly but subsequent calls, especially if i change the length of the filename causes the code to break. I am not really sure.
I also noticed that the length of my res_dir changes which I really don't understand.
along with the accepted answer, here is my new code w/o magic numbers
static void initResourcePath(void)
{
char *base_path = getBasePath();
size_t len = strlen(base_path) *2; //making enough space
size_t i, sz = 0;
char tmp[len];
while(base_path[i] != '\0')
{
if(base_path[i] == 'b' && base_path[i+1] == 'i' && base_path[i+2] == 'n')
{
sz = i;
}
tmp[i] = base_path[i];
i++;
}
char* b = strstr(tmp, "/bin");
memcpy(b, "/bin/resources/",15);
tmp[ sz + 14 ] = '\0';
res_dir = (char*)malloc(sizeof(char) * (strlen(tmp) +1));
strcpy(res_dir, tmp);
free(base_path);
}
The problem you're having is here:
res_dir = (char*)malloc(sizeof(char) * (sz + 4));
You're not allocating enough space. You probably meant to use sz + 14 instead of sz + 4. That's one of the issues with using magic numbers as WhozCraig mentioned.
Rather than doing something convoluted like that, you know that you're copying tmp into res_dir, so do this instead:
res_dir = malloc(strlen(tmp)+1);
Note that the return value of malloc is not being casted. Doing so in C can hide subtle bugs if you fail to #include <stdlib.h>.
Related
scanFolderPath - path of folder with files.
filesToScan - array of strings with the files name.
I have problem with the realloc line (the third line in the for loop). And I don't understand why! Thank you for helping programmers community ;)
char* filePath = malloc(0);
char* fileContent = 0;
char* partContent = 0;
FILE* fileToScan;
int i = 0, j = 0, virus = FALSE, flag = FALSE, counter = 0;
for (i = 0; i < amountOfFiles; i++)
{
flag = FALSE;
if (scanFolderPath != NULL && filesToScan[i] != NULL)
{
realloc(filePath, (sizeof(char) * (strlen(scanFolderPath) + 1 + strlen(filesToScan[i]))));
}
strcpy(filePath, "");
getFilePath(filePath, scanFolderPath, filesToScan[i]);
fileToScan = fopen(filePath, "rb");
readFile(&fileContent, filePath);
if (choice == '0')
{
virus = scanSingature(fileContent, virusSingature, getLength(fileToScan), virusSingatureLen);
if (virus)
{
printf("%s - Infected!\n", filePath);
fprintf(logsFile, "%s", filePath);
fprintf(logsFile, " Infected!\n");
}
else
{
printf("%s - Clean\n", filePath);
fprintf(logsFile, ("%s", filePath));
fprintf(logsFile, " Clean\n");
}
fclose(fileToScan);
strcpy(filePath, "");
}
}
try
filePath = realloc(filePath, (sizeof(char) * (strlen(scanFolderPath) + 1 + strlen(filesToScan[i]))));
that way the contents of filepath are reallocated, and the pointer is returned to filepath
realloc returns new allocated block. You do not assign to anything so the reallocated memory is lost and your pointer is pointing to the invalid memory assuming realloc success).
The correct way of reallocating:
void *p = malloc(10);
void t;
/* ... */
t = realloc(p, 20);
if(t) p = t; //check if the realloc was successful
/* ... */
free(p)
I'm working on a client, server project. I receive a response from the server where I have to create two files. The first file is a .html file and the second file is .png file. I parse the response and I try to dynamically create the files in a while loop.
...
FILE *fwrp;
char *response = malloc(MAXDATASIZE * sizeof(char));
memset(response, '\0', sizeof(char) * MAXDATASIZE);
char *r = &response[0];
while (fread(field, sizeof(field), 1, fpr)) {
for (int i = 0; i < MAXDATASIZE; i++) {
*r = field[i];
r++;
//Some unecessary code...
if (strstr(response,"file=")){
char* newFileName = strchr(response, '=');
newFileName++;
fwrp = fopen(newFileName, "w");
data = false;
//...
I hope I didn't cut too much necessary information. The problem is the following: The files are created. Also with the right content.
The problem just the dynamic name of the file. One time the name should be ok.png, but instead it is 'ok.png'$'\n'
The same problem for the html file. The name should be example.html but is 'example.html'$'\n'
Already tried to print the names before they are created. They have the right format when they are printed. And I tried to allocate the memory with strdup, but it did not work for some reason. Anybody have an idea why this problem appears?
SOLUTION:
For those who are interested. Here is my solution
int receiveResponse(int sockfd) {
int sdw = dup(sockfd);
FILE *fpr = fdopen(sdw, "r");
FILE *fwrp;
int lenOfRecord = 0;
bool data = false;
bool status_checked = false;
bool first = true;
unsigned char field[MAXDATASIZE] = {0};
char *response = malloc(MAXDATASIZE * sizeof(char));
memset(response, '\0', sizeof(char) * MAXDATASIZE);
char *r = &response[0];
while (fread(field, sizeof(field), 1, fpr)) {
for (int i = 0; i < MAXDATASIZE; i++) {
*r = field[i];
r++;
if ((field[i] == '\n') && (data == false)){
if (strstr(response, "status=") && (status_checked == false)){
status_checked = true;
char* status = strchr(response,'=');
status++;
}
if (strstr(response, "len=")){
char *len = strchr(response, '=');
len++;
char *ptr;
lenOfRecord = strtol(len,&ptr,10);
data = true;
first = true;
}
if (strstr(response,"file=")){
char* tmp = strchr(response, '=');
tmp++;
char* newFileName = malloc(strlen(tmp) * sizeof(char));
memcpy(newFileName, tmp, strlen(tmp) * sizeof(char));
newFileName[strlen(newFileName) - 1] = 0;
fwrp = fopen(newFileName, "w");
free(newFileName);
data = false;
}
free(response);
char* response = malloc(MAXDATASIZE * sizeof(char));
memset(response, '\0', sizeof(char) * MAXDATASIZE);
r = &response[0];
}
if (--lenOfRecord == 0){
data = false;
fflush(fwrp);
fclose(fwrp);
}
if ((data == true) && (first == false)) {
fputc(field[i], fwrp);
}
if ((data == true) && (first == true)){
first = false;
}
}
}
}
So the problem was solved with this modification
newFileName[strlen(newFileName) - 1] = 0;
I've no idea, why are you copying readed field content into response instead of reading strictly into response. Additionaly, you didn't show the declaration of field.
Probably you should take the better care on count of readed chars (returned by fread()): it can be negative (means: error), not only positive or 0.
What about zero-termination?
So, my proposition is:
//...
// for better readability
#define MAX_RESPONSE_SIZE (MAXDATASIZE * sizeof(char))
// below: added 1 byte for preserving the proper string termination ('\0' byte)
#define RESPONSE_BUFFER_SIZE (MAXDATASIZE + 1)
FILE *fwrp;
char *response = malloc(RESPONSE_BUFFER_SIZE);
memset(response, '\0', RESPONSE_BUFFER_SIZE);
int readOffset = 0; // offset for reading the next chunk
int readCount; // count of readed characters/bytes
// below: return of fread() can be positive, 0 if no more data, or negative if error
while ((readCount = fread(response + readOffset, MAX_RESPONSE_SIZE - readOffset, 1, fpr)) > 0) {
readOffset += readCount;
}
//Some unecessary code...
if (strstr(response, "file=")) {
char* newFileName = strchr(response, '=');
newFileName++;
fwrp = fopen(newFileName, "w");
data = false;
//...
Following is a part of a file that needs to be parsed
record(ai, "SRC01-VA-IMG1:getPressure")
{
field(DESC, "Reads Cell SR-GC1 Pressure")
field(SCAN, "1 second")
field(DTYP, "stream")
field(INP, "#vacuum-XGS600-gc.proto getPressure(1) SR-GC1")
field(PINI, "YES")
field(VAL, "0")
field(PREC, "3")
field(LOLO, "") field(LLSV, "NO_ALARM")
field(HIGH, "") field(HSV, "NO_ALARM")
field(HIHI, "") field(HHSV, "NO_ALARM")
}
The parsing process will read the record name (In the qoutes) and type (ai, in the line record), and each field type and value (in any line that starts with field. e.g. Type: PINI, Value: "YES"). Note that each line can contain more than one record definition. The example contains some interesting cases like multiple fields on the same line, parenthesis inside qoutes, etc.
Here is my code for that purpose:
struct field
{
char* name;
char* value;
};
struct record
{
char* name;
char* type;
struct field* fields;
};
struct record* get_records(char* file, int* length)
{
size_t SIZE = 0;
size_t fSIZE = 1;
const int N = 100;
struct record* records = malloc(1 * sizeof(struct record));
struct field* fields;
// char line[N];
char* line = malloc(N);
char record_name[100];
char record_type[10];
char field_name[10];
char field_value[100];
char temp[100];
int open, close, comma, q1, q2;
FILE* fp = fopen(file, "r");
if(fp != NULL)
{
while(fgets(line, N, fp))
{
line = strtrim(line);
if(strncmp(line, "record", 6) == 0)
{
memset(record_name, 0, sizeof(record_name));
memset(record_type, 0, sizeof(record_type));
struct record* r = malloc(sizeof(struct record));
open = strchr(line, '(') - line + 1;
close = strchr(line, ')') - line + 1;
comma = strchr(line, ',') - line + 1;
q1 = strchr(line, '"') - line + 1;
q2 = strrchr(line, '"') - line + 1;
strncpy(record_type, &line[open], comma - open - 1);
strncpy(record_name, &line[q1], q2 - q1 - 1);
record_name[q2 - q1 - 1] = '\0';
record_type[comma - open - 1] = '\0';
r->name = record_name;
r->type = record_type;
printf("Name: %s\n", r->name);
printf("Type: %s\n", r->type);
fSIZE = 0;
fields = malloc(100 * sizeof(field)); // HERE
while(fgets(line, N, fp))
{
struct field* f = malloc(sizeof(struct field));
if(strncmp(line, "}", 1) == 0)
break;
if(strncmp(line, "{", 1) == 0)
continue;
line = strtrim(line);
int i1 = 0;
int i2 = 0;
char* p1 = strstr(line, "field");
char* p2;
while(p1 != NULL)
{
i1 = p1 - line;
p2 = strstr(p1 + 1, "field");
if(p2 != NULL)
{
i2 = p2 - line;
p1 = strstr(p1 + 1, "field");
}
else
{
i2 = strlen(line);
p1 = NULL;
}
memset(temp, 0, sizeof(temp));
memset(field_name, 0, sizeof(field_name));
memset(field_value, 0, sizeof(field_value));
strncpy(temp, &line[i1], i2 - i1); temp[i2-i1] = '\0';
printf("Line2 : %s\n", temp);
open = strchr(temp, '(') - temp + 1;
close = strrchr(temp, ')') - temp + 1;
comma = strchr(temp, ',') - temp + 1;
q1 = strchr(temp, '\"') - temp + 1;
q2 = strrchr(temp, '\"') - temp + 1;
strncpy(field_value, &temp[q1], q2 - q1 - 1); field_value[q2-q1-1] = '\0';
strncpy(field_name, &temp[open], comma - open - 1); field_name[comma-open-1] = '\0';
printf("Name : %s\n", field_name);
printf("Value: %s\n\n", field_value);
f->name = field_name;
f->value = field_value;
fields[fSIZE++] = *f;
}
free(line);
line = malloc(N);
}
r->fields = fields;
records[SIZE++] = *r;
}
else
continue;
}
}
else
{
printf("%s\n", "Unable to open file.");
exit(1);
}
*length = SIZE;
// fclose(fp);
return records;
}
int main()
{
int length = 0;
struct record* records = get_records("./test.db", &length);
// printf("Anything \n");
int i = 0;
for(i = 0; i < length; i++)
{
struct record* r = (struct record*) &records[i];
printf("Name: %s\n", r->name);
printf("Type: %s\n", r->type);
}
return 0;
}
Now I have two issues with this implementation which I could not figure out:
In the main function there is a printf statement, if uncommented the printf inside the loop will print garbage, otherwise correct output.
Having fclose in the function get_records uncommented gives a Segmentation fault (core dumped). With trial and error I figured out I either use it or use the malloc line designated by the comment HERE, for some reason using one of them or non the fault goes away. I understand I have something wrong with memory allocation somewhere, I used valgrind but it did not help me locating anything
Notes:
Constant numbers used in malloc are for testing purposes. We have files that contains 100's of records. This leads to a future question, which is better use large enough malloc buffer or use realloc?
Any other implementation in C, if any, is welcome :)
Seems like memory was massively messed up by this implementation due to many calls for malloc and free. What I did was to replace char* in the structs with arrays and line definition converted to char[] and dereference it in strtrim call.
I wrote a program that worked well without any errors.
I read a text file and write the contents to an array (line by line and seperat strings in this line one by one). Then I added a second textfile and again tried to read the content but then I got some crazy segmentation faults that are only reported when I debug my program.
This is the part of the program that causes the error:
vrFile = fopen("file.txt","r");
//some temporary arrays
float taz[5000], tel[5000], ttime[5000], tvr[5000][nbins], tdbz[5000][nbins];
int size = 1024, pos;
int c;
//buffer for the line to read
char *buffervr = (char *)malloc(size);
int lin=0;
if(vrFile) {
do { // read all lines in file
pos = 0;
do{ // read one line
c = fgetc(vrFile);
if(c != EOF) buffervr[pos++] = (char)c;
if(pos >= size - 1) { // increase buffer length if line is too long - leave room for 0
size *=2;
buffervr = (char*)realloc(buffervr, size);
}
}while(c != EOF && c != '\n');
buffervr[pos] = 0;
// line is now in buffer
char *ptr;
ptr = strtok(buffervr,"\t");
int abs=1;
while(ptr != NULL) {
if(abs==1){
taz[lin] = atof(ptr);
}
else if(abs==2) {
tel[lin] = atof(ptr);
}
else if (abs==3) {
ttime[lin] = atof(ptr);
}
else {
tvr[lin][abs-4]=atof(ptr);
}
abs++;
ptr = strtok(NULL, "\t");
}
lin++;
} while(c != EOF);
fclose(vrFile);
}
//free(buffervr);
The first thing is that I get a segmentation fault when I try to allocate a buffer char *buffervr = (char *)malloc(size);. When I do this before I allocate the arrays float taz[5000], tel[5000], ttime[5000], tvr[5000][nbins], tdbz[5000][nbins]; it works?!
The second thing is that I cant read the file with c = fgetc(vrFile); although I can open it. Here I get another segmentation fault?!
Can someone tell me that went wrong?
Thank you!
EDIT: actual code:
int size = 1024, pos;
int c, cdbz;
char *buffervr = (char *)malloc(size);
char *bufferdbz = (char *)malloc(size);
int lin=0;
char *taz, *tel, *ttime, **tvr, **tdbz;
taz=(char *) malloc(5000*sizeof(char));
tel=(char *) malloc(5000*sizeof(char));
ttime=(char *) malloc(5000*sizeof(char));
tvr = malloc(5000 * sizeof(char *));
int i;
for(i = 0; i < 5000; i++) {
tvr[i] = malloc(nbins * sizeof(char));
}
tdbz = malloc(5000 * sizeof(char *));
for(i = 0; i < 5000; i++) {
tdbz[i] = malloc(nbins * sizeof(char));
}
//float taz[5000], tel[5000], ttime[5000], tvr[5000][nbins], tdbz[5000][nbins];
if(vrFile!=NULL) {
do { // read all lines in file
pos = 0;
do{ // read one line
c = fgetc(vrFile);
if(c != EOF) buffervr[pos++] = (char)c;
if(pos >= size - 1) { // increase buffer length - leave room for 0
size *=2;
buffervr = (char*)realloc(buffervr, size);
}
}while(c != EOF && c != '\n');
buffervr[pos] = 0;
// line is now in buffer
char *ptr;
ptr = strtok(buffervr,"\t");
int abs=1;
while(ptr != NULL) {
if(abs==1){
taz[lin] = (ptr);
}
else if(abs==2) {
tel[lin] = (ptr);
}
else if (abs==3) {
ttime[lin] = (ptr);
}
else {
tvr[lin][abs-4]=(ptr);
}
abs++;
ptr = strtok(NULL, "\t");
}
lin++;
} while(c != EOF);
fclose(vrFile);
}
free(buffervr);
.
.
.
int lins,abss;
for (lins=0; lins<lin; lins++)
{
time[0]=ttime[lins];
az[0]=taz[lins];
el[0]=tel[lins];
for (abss=0; abss<nbins; abss++)
{
vr[abss]=tvr[lins][abss];
//dbZ[abss]=tdbz[lins][abss];
}
}
note: time, lat, lon, az, el and vr are pointers.
EDIT: I solved my Problem this way:
vrFile = fopen("file.txt","r");
if (vrFile != NULL){
while ((getline(&line, &len, vrFile)) != -1) {
NumberOfLines++;
if(NumberOfLines == 1){
line = strtok(line, "\t");
while(line != NULL){
NumberOfDoubles++;
line = strtok(NULL, "\t");
}
}
}
}
rewind(vrFile);
int i,j;
float* taz;
float* tel;
float* ttime;
float** tvr;
float** tdbz;
//1D Arrays
taz = (float*) malloc (sizeof(float)*NumberOfLines);
tel = (float*) malloc (sizeof(float)*NumberOfLines);
ttime = (float*) malloc (sizeof(float)*NumberOfLines);
//2D Arrays
tvr = (float**) malloc (sizeof(float*)*NumberOfLines);
for(i=0;i<NumberOfLines;i++){
tvr[i] = (float*) malloc (sizeof(float)*NumberOfDoubles);
}
tdbz = (float**) malloc (sizeof(float*)*NumberOfLines);
for(i=0;i<NumberOfLines;i++){
tdbz[i] = (float*) malloc (sizeof(float)*NumberOfDoubles);
}
if (vrFile != NULL){
i = 0;
while ((getline(&line, &len, vrFile)) != -1) {
line = strtok(line, "\t");
j = -3;
while(line != NULL){
switch(j){
case -3: taz[i] = strtod(line, NULL);break;
case -2: tel[i] = strtod(line, NULL);break;
case -1: ttime[i] = strtod(line, NULL);break;
default: tvr[i][j] = strtod(line, NULL);break;
}
line = strtok(NULL, "\t");
j++;
}
i++;
}
}
I'm trying to learn C (which is freaking hard...) so I wanted to write a routine which gets a line of a file. I created this function :
int c;
int buflen = 100;
if((*buffer = malloc(sizeof(char) * buflen)) == NULL) {
DXLogWarn("Not enough memory");
return;
}
char * dst = *buffer;
char * end = *buffer + buflen - 1;
while ((c = getc(fp)) != EOF) {
if (c == '\n') {
break;
}
if (dst < end) {
*dst++ = c;
}
}
*dst = '\0';
Which works yay! But now I thought instead of cutting of the last part of the string I could realloc the buffer and continue till the '\n'. So I changed it to this:
void fget_line(FILE *fp, char **buffer) {
int c;
int buflen = 10;
if((*buffer = malloc(sizeof(char) * buflen)) == NULL) {
DXLogWarn("Not enough memory");
return;
}
char * dst = *buffer;
char * end = *buffer + buflen - 1;
while ((c = getc(fp)) != EOF) {
if (c == '\n') {
break;
}
if (dst < end) {
*dst++ = c;
} else {
buflen *= 2;
*buffer = realloc(*buffer, buflen * sizeof(char));
if (*buffer == NULL) {
DXLogError("Err");
return;
}
}
}
*dst = '\0';
}
Which gives me an error : malloc: * error for object 0x10a8001b8: incorrect checksum for freed object - object was probably modified after being freed.
* set a breakpoint in malloc_error_break to debug
Which I do not get. What am I doing wrong?
at the start you do:
char * dst = *buffer;
char * end = *buffer + buflen - 1;
This set dst and end to the correct positions inside buffer. Then you reallocate buffer:
*buffer = realloc(*buffer, buflen * sizeof(char));
This causes buffer to get a new value which is probably different then before. So you also have to update dst and end to the new positions inside buffer.
Changing end is easy, but because you keep changing dst, it is difficult to calculate the new value. So instead of changing the pointers, it might be easier to store just the offset in a integer. Something like:
int pos=0;
while ((c = getc(fp)) != EOF) {
if (c == '\n') {
break;
}
if (pos >= buflen-1) {
buflen *= 2;
*buffer = realloc(*buffer, buflen * sizeof(char));
if (*buffer == NULL) {
DXLogError("Err");
return;
}
}
(*buffer)[pos] = c;
pos++;
}
(*buffer)[pos] = '\0';
I also changed the if statement above, as you did not store the character which caused the reallocation.