I am trying to copy some strings to strings in a struct using strcpy. I am posting the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct floating_point{
char sign[2];
char exponent[9];
char fraction[24];
}FLOATING_POINT;
FLOATING_POINT stringToFloatingPoint(char* str){
struct floating_point fp;
char *integer_str,*fraction_str,*integer_bin,*fraction_bin,*sign;
sign=(char*)malloc(2*sizeof(char));
int i=1,integer=0,fraction=0,comma=0,remainder=0,size=0;
double fraction_double;
//str=(char*)malloc(200*sizeof(char));
//str="108,53";
char * pch=(char*)malloc((strlen(str)+1)*sizeof(char));
pch=strchr(str,',');
if(pch==NULL){
pch=str+strlen(str);
}
comma=pch-str;
integer_str=(char*)malloc((comma+1)*sizeof(char));
strncpy(integer_str,str,comma);
integer_str[comma]='\0',
integer=atoi(integer_str);
fraction_str=(char*)malloc((strlen(str)-comma+2)*sizeof(char));
strncpy(fraction_str,str+comma+1,strlen(str)-1);
fraction_str[strlen(str)-comma]='\0';
fraction=atoi(fraction_str);
printf("%d",fraction);
printf("%s",fraction_str);
if(integer<0){
strcpy(sign,"1");
integer=-1*integer;
}
else{
strcpy(sign,"0");
}
size=(int)(log(integer)/log(2))+2;
integer_bin=(char*)malloc(size*sizeof(char));
while(integer>0){
remainder=fmod(integer,2);
integer=integer/2;
*(integer_bin+size-i-1)=(char)(remainder+48);
i++;
}
*(integer_bin+size-i-1)=(char)(integer+48);
*(integer_bin+size-1)='\0';
printf("%s\n",integer_bin);
fraction_bin=(char*)malloc(24*sizeof(char));
fraction_double=atof(fraction_str);
fraction_double=fraction_double/(pow(10,strlen(fraction_str)));
printf("frac= %f",fraction_double);
i=0;
while((i<23)&&fraction_double!=0){
fraction_double=2*fraction_double;
if(fraction_double<1){
*(fraction_bin+i)='0';
}
else{
fraction_double=fraction_double-1;
*(fraction_bin+i)='1';
}
i++;
}
*(fraction_bin+i)='\0';
printf("\n%s",integer_bin);
printf("\n%s",fraction_bin);
size=strlen(integer_bin);
for(i=0;i<strlen(fraction_bin)-(size-1);i++){
*(fraction_bin+strlen(fraction_bin)-1-i)=*(fraction_bin+strlen(fraction_bin)-size-i);
}
for(i=1;i<size;i++){
*(fraction_bin+i-1)=*(integer_bin+i);
}
printf("\n%s",fraction_bin);
free(integer_bin);
integer_bin=(char*)malloc(9*sizeof(char));
strcpy(integer_bin,"00000000");
printf("integer_bin %s",integer_bin);
integer=127+size-1;
i=1;
while(integer>0){
remainder=fmod(integer,2);
integer=integer/2;
*(integer_bin+8-i)=(char)(remainder+48);
i++;
}
*(integer_bin+8-i)=(char)(integer+48);
*(integer_bin+8)='\0';
printf("\n\n%s %s %s",sign,integer_bin,fraction_bin);
strcpy(fp.exponent,integer_bin);
strcpy(fp.sign,sign);
strcpy(fp.fraction,fraction_bin);
free(integer_bin);
free(integer_str);
free(fraction_bin);
free(fraction_str);
free(sign);
free(pch);
}
int main()
{
struct floating_point fp=stringToFloatingPoint("108,53");
printf("\n\n%s %s %s",fp.sign,fp.exponent,fp.fraction);
}
Everything works well till the strcpy part.
printf("\n\n%s %s %s",sign,integer_bin,fraction_bin);
This printf works well. And the size of my strings are equal to the ones in the struct. You can see how much memory I have allocated using malloc.
I dont get an error but when I print the values in my main funciton they are not correct.
What can the problem be?
Your function is missing its return statement.
You should pay more attention to the compiler warnings, or turn more warnings on, or get a better compiler.
You missed a return in the function stringToFloatingPoint... at least this one is a problem...
Add
Just to let you know, executing gcc -std=c99 -pedantic -Wall ./boh.c -lm or similar for your compiler, would have say:
./boh.c: In function ‘stringToFloatingPoint’:
./boh.c:105: warning: control reaches end of non-void function
Valgrind would say:
==6480== HEAP SUMMARY:
==6480== in use at exit: 7 bytes in 1 blocks
==6480== total heap usage: 7 allocs, 7 frees, 59 bytes allocated
==6480==
==6480== LEAK SUMMARY:
==6480== definitely lost: 7 bytes in 1 blocks
You mostly can avoid allocation, especially of two chars or so...
Moreover, running it will give a problem (double free or corruption)...
Likely the leak is here:
char * pch=(char*)malloc((strlen(str)+1)*sizeof(char));
pch=strchr(str,',');
if(pch==NULL){
pch=str+strlen(str);
}
Here you are allocating memory, then you search for a char and trash the pointer to the allocated memory... If you then will try to free(pch), you will cause a problem...
Your function is specified as returning a FLOATING_POINT structure:
FLOATING_POINT stringToFloatingPoint(char* str)
But nowhere in the function is there a return statement.
Related
Edit: I made some changes at my code.
I want to write a line fitting program by using the data from two .txt file. The code is as following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int data_read(char programs_x[], char programs_y[]) {
int i=0, j=0, k;
int numProgs_x=0;
int numProgs_y=0;
char line_x[1024];
char line_y[1024];
FILE *file_x;
FILE *file_y;
file_x = fopen("data_x.txt", "r");
file_y = fopen("data_y.txt", "r");
while(fgets(line_x, sizeof line_x, file_x)!=NULL) {
//check to be sure reading correctly
//printf("%s", line_x);
//add each filename into array of programs
programs_x[i]=strdup(line_x);
i++;
//count number of programs in file
numProgs_x++;
}
while(fgets(line_y, sizeof line_y, file_y)!=NULL) {
//check to be sure reading correctly
//printf("%s", line_y);
//add each filename into array of programs
programs_y[j]=strdup(line_y);
j++;
//count number of programs in file
numProgs_y++;
}
fclose(file_x);
fclose(file_y);
return 0;
}
int main ( void ) {
int i, j, k, n=1024;
float s1=0,s2=0,s3=0,s4=0,a,d,b;
char programs_x[1024], programs_y[1024];
data_read(programs_x, programs_y);
for(i=0;i<n;i++) {
scanf("%f", &programs_x[k]);
}
for(i=0; i<n; i++){
scanf("%f", &programs_y[k]);
}
for(i=0;i<n;i++) {
s1=s1+programs_x[i];
s2=s2+programs_x[i] * programs_x[i];
s3=s3+programs_y[i];
s4=s4+programs_x[i] * programs_y[i];
}
d=n*s2-s1*s1;
a=(s2*s3-s1*s4)/d;
b=(n*s4-s1*s3)/d;
printf("\nThe values of a and b are : %f\t%f\n",a,b);
printf("\nThe Required Linear Relation is : \n");
if(b>0){
printf("\ny=%f+%fx\n",a,b);
}
else {
printf("y=%f%fx",a,b);
}
return 0;
}
When I try to compile this code, the compiler shows these error:
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
test3.c:
Error E2349 test3.c 22: Nonportable pointer conversion in function data_read
Error E2349 test3.c 33: Nonportable pointer conversion in function data_read
*** 2 errors in Compile ***
How do I fix the errors? Where did I make mistakes in declaring and calling the data types? I'm pretty sure I declare programs_x and programs_y as char this time and not int.
The error is difficulty to pin down as we don't have line numbers but this line is definitely not right in your main:
data_read(char programs_x[], char programs_y[]);
To call a function you just list the variables and values you're passing to it like this:
data_read(programs_x, programs_y);
Which will no doubt cause more errors/warnings to be flagged as you declare programs_x and programs_y as arrays of int, but data_read is expecting arrays of char. So there's a conflict in what you think your function wants and what you're providing to it which you need to sort out.
The error could mean that the non-standard function strdup() is not supported. A C compiler does not need to support it, which is why it is a good idea to avoid that function. If the function is supported as a non-standard extension (it is part of POSIX), you might find it in the header <string.h> which you didn't include.
As for the cause of the rest of the errors, I have no idea, since those appear to originate from other files than the one you posted.
I have defined a structure StructA and function StructA createStructA(...) that creates and returns a new StructA. I want to have a function foo() that will explicitly return int error code as well as a new StructA that I want to use outside foo(). So it seems I need pointers to pointers:
int foo(StructA **pA) {
// Allocate some memory:
*pA = malloc(sizeof(StructA)); // (Editor's note: don't cast the return of malloc.)
// check that malloc() didn't error.
assert(*pA);
// Fill out a new StructA with createStructA():
StructA a = createStructA(...);
// return
*pA = &a;
return 0;
}
Why does this code exit with segmentation fault? It appears it is due to malloc as if I comment out all other lines except for malloc line it still breaks with segfault
As the code above may seem unclear, here is MCVE of my problem:
#include <stdio.h>
#include <malloc.h>
typedef struct {
int x;
int y;
} A;
typedef struct {
A a;
int z;
} B;
A makeA() {
return (A) {.x = 1, .y = 2};
}
B makeB(A a1) {
return (B) {.a = a1, .z = 3};
}
void parseA(A **ppa) {
*ppa = malloc(sizeof(A)); // crashes with segfault here
**ppa = makeA();
}
void parseB(B **ppb) {
A **ppa;
parseA(ppa);
// todo make B .. but it's already crashing
}
int main() {
B **ppb;
parseB(ppb);
return 0;
}
*pA = &a set the *pA pointing to a local variable within function foo. When function returns, local variable is out of scope, therefore *pA becomes invalid.
Edit:
Just read your new code. In this line, *ppa = malloc(sizeof(A)); // crashes with segfault here, ppa is not a valid pointer yet, you cannot dereference it by *ppa. Need to do ppa = (A**)malloc(sizeof(A*));first.
Actually, I make a guess here, this is want you want:
void parseA(A **ppa) {
*ppa = (A*)malloc(sizeof(A));
// todo make A, e.g. ppa->x = 1;
}
void parseB(B **ppb) {
A *ppa = NULL;
parseA(&ppa);
// ppa is a valid point now, you can do, e.g. ppa->y=1;
// todo make B
}
In addition to the other corrections, if you will need ppa back in the calling function main, you have no way of returning a value to main. While there is exercise value in what you are doing, your actual goal is anything but clear. It is somewhat of an XY problem, see: What is the XY problem?.
That said, reading between the lines, and to make ppa available back in main, your parseB would have to somehow return a value. You could do so by changing the type to A *parseB (B **ppb).
Further, you seem to have a bit of confusion in whether to declare ppa and ppb as pointers or pointer-to-pointer-to-type. Given your initialization and use, it appears you want a pointer to both ppa and ppb. You would then pass the address of each to the functions parseB and parseA and dereference accordingly to allocate storage for their contents. Doing so, you could craft a parseB similar to:
A *parseB (B **ppb)
{
A *ppa = NULL;
void *tmp = realloc (*ppb, sizeof **ppb);
if (!tmp) {
fprintf (stderr, "error: realloc ppb.\n");
return NULL;
}
*ppb = tmp;
parseA (&ppa);
if (ppa)
**ppb = makeB (*ppa);
return ppa;
}
note: realloc is used for the allocation, because you have no control over whether *ppb has been previously allocated within parseB itself (you do have control over what you send to parseA from parseB so malloc is fine in parseA)
To start this daisy-chain of allocation and assignment of values, your main could be written similar to:
int main ()
{
B *ppb = NULL;
A *ppa = parseB (&ppb);
if (ppa && ppb) {
printf ("ppa->x: %d\nppa->y: %d\n\n"
"ppb->a.x: %d\nppb->a.y: %d\nppb->z: %d\n",
ppa->x, ppa->y, ppb->a.x, ppb->a.y, ppb->z);
free (ppa);
free (ppb);
}
return 0;
}
Granted, I do not have a clear picture of what you are ultimately attempting to accomplish. So to make use of the values you assign, the pointer level of indirection at the declaration was reduced to make sense of what it looked like you were trying to do. That said, and putting all the pieces together, you could do something similar to the following:
#include <stdio.h>
#include <malloc.h>
typedef struct {
int x;
int y;
} A;
typedef struct {
A a;
int z;
} B;
A makeA ()
{
return (A) {.x = 1,.y = 2};
}
B makeB (A a1)
{
return (B) {.a = a1,.z = 3};
}
void parseA (A **ppa)
{
*ppa = malloc (sizeof (A));
**ppa = makeA ();
}
A *parseB (B **ppb)
{
A *ppa = NULL;
void *tmp = realloc (*ppb, sizeof **ppb);
if (!tmp) {
fprintf (stderr, "error: realloc ppb.\n");
return NULL;
}
*ppb = tmp;
parseA (&ppa);
if (ppa)
**ppb = makeB (*ppa);
return ppa;
}
int main ()
{
B *ppb = NULL;
A *ppa = parseB (&ppb);
if (ppa && ppb) {
printf ("ppa->x: %d\nppa->y: %d\n\n"
"ppb->a.x: %d\nppb->a.y: %d\nppb->z: %d\n",
ppa->x, ppa->y, ppb->a.x, ppb->a.y, ppb->z);
free (ppa); /* if you allocate it, it is up to you to free it */
free (ppb);
}
return 0;
}
Example Use/Output
$ ./bin/structptrissue
ppa->x: 1
ppa->y: 2
ppb->a.x: 1
ppb->a.y: 2
ppb->z: 3
Memory Error Check
In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.
It is imperative that you use a memory error checking program to insure you do not attempt to write beyond/outside the bounds of your allocated block of memory, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.
For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.
$ valgrind ./bin/structptrissue
==19399== Memcheck, a memory error detector
==19399== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==19399== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==19399== Command: ./bin/structptrissue
==19399==
ppa->x: 1
ppa->y: 2
ppb->a.x: 1
ppb->a.y: 2
ppb->z: 3
==19399==
==19399== HEAP SUMMARY:
==19399== in use at exit: 0 bytes in 0 blocks
==19399== total heap usage: 2 allocs, 2 frees, 20 bytes allocated
==19399==
==19399== All heap blocks were freed -- no leaks are possible
==19399==
==19399== For counts of detected and suppressed errors, rerun with: -v
==19399== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Always confirm that you have freed all memory you have allocated and that there are no memory errors.
Look things over and let me know if you have further questions.
cJSON memory leak is a post where a memory leak occured. But the problem n this case is the cJSON_Print() function.
I did not even use this function (have commented it for the time being) and have still a memory leakage. My ode looks like this
void myFunc(cJSON* ptr)
{
/*some code */
// I have used some sint32 numbers from another library for simplicity
// i will use int
int num = 30
cJSON_AddItemToArray(pt_data,cJSON_CreateNumber(num));
}
int main()
{
cJSON *root =cJSON_CreateObject();
cJSON *pt_PPC= cJSON_CreateArray();
cJSON_AddItemToObject(root,"PowerPC",pt_PPC);
cJSON *pt_data = cJSON_CreateArray();
cJSON_AddItemToArray(pt_PPC,pt_data);
int i;
for(i=0;i<10;i++)
myFunc(pt_PPC);
cJSON_Delete(root);
return 0;
}
The memory increases with time.
Any suggestions?
I've tried your code in VS2015 and found that your myFunc function does not even compile! The function cJSON_AddItemToObject takes three parameters and num is not even defined.
I tried with the following code:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include "cJSON.h"
void myFunc(cJSON* ptr)
{
/*some code */
cJSON_AddItemToObject(ptr, "Item", cJSON_CreateNumber(10.0));
}
int main()
{
cJSON *root = cJSON_CreateObject();
cJSON *pt_PPC = cJSON_CreateObject();
cJSON_AddItemToObject(root, "PowerPC", pt_PPC);
myFunc(pt_PPC);
cJSON_Delete(root);
_CrtDumpMemoryLeaks();
}
I enabled memory leak debugging (Link to Article) and used _CrtDumpMemoryLeaks() to print the possible memory leaks if any (to the debug output window).
There were no memory leaks detected.
Your code is not complete and has syntax errors so it's not possible to tell where the problem exactly is by looking at it.
Anyway it's most likely you're creating a JSON object (somewhere) and forgetting to add it to the root object or any of its descendants. When the root object is deleted the un-connected elements are not deleted and leaks memory.
Hope this helps.
I have found the problem. The problem is still somehow in the cJSON lib. Inside a function i am doing something like this.
uint8 *arr;
arr = (uint8 *)malloc(t_DataVariableInfo.s32_Size);
getvariables(&arr); // this function gets some variables from a datapool
//pt_data is the pointer of cJSON where this number has to be added
cJSON_AddItemToArray(pt_data,cJSON_CreateNumber(arr[i]));
free(arr);
Now because of some reason arr could not be freed. The cJSON_CreateNumber() function is maybe doing some changes in it. I got it to work by doing this
uint8 *arr;
arr = (uint8 *)malloc(t_DataVariableInfo.s32_Size);
uint8 *address = arr;
getvariables(&arr); // this function gets some variables from a datapool
//pt_data is the pointer of cJSON where this number has to be added
cJSON_AddItemToArray(pt_data,cJSON_CreateNumber(arr[i]));
free(address);
Thanks for the help. Sorry i could not post all the code. Is this a problem of cJSON_CreateNumber()??
I'm getting the error you may see in the title, and I can't figure out why.
The code:
#include <cstdlib>
#include <cstdio>
struct CData {
int* num;
char* adr;
char* ph;
void (*init)(CData* owner);
void (*del)(CData* owner);
char* (*getAdr)(CData* owner);
void (*setAdr)(CData* owner, char* adr);
};
void CData_init(CData* owner) {
owner->num = (int*)malloc(sizeof(int));
owner->adr = (char*)malloc(sizeof(char)*255);
owner->ph = (char*)malloc(sizeof(char)*255);
}
void CData_del(CData* owner) {
free(owner->num);
free(owner->adr);
free(owner->ph);
}
char* CData_getAdr(CData* owner) {
return owner->adr;
}
void CData_setAdr(CData* owner, char* adr) {
owner->adr = adr;
}
int main() {
CData* data = (CData*)malloc(sizeof(CData));
data->init = CData_init;
data->del = CData_del;
data->getAdr = CData_getAdr;
data->setAdr = CData_setAdr;
data->init(data);
data->setAdr(data, "asdasd");
printf("%d", data->getAdr(data));
data->del(data);
free(data);
return 0;
}
So I think the error is caused by the char* manipulations but I don't know why.
What I want to do is I want it to be possible to pass a string as a parameter to data->setAdr and I want it to be assigned to the variable afterwards.
Compiling line:
gcc -o test main.cpp
data->setAdr(data, "asdasd"); is problematic.
You are setting the address of a memory block that is not allocated by malloc and later trying to free it with free. Freeing such memory blocks (not allocated by malloc) except NULL pointer lead to undefined behavior.
This is also leaking atleast 255 bytes of memory in your case. valgrind can help you understand better in this case.
Changing following function should fix this (Rename it appropriately)
void CData_setAdr(CData* owner, char* adr) {
strcpy(owner->adr, adr); /* include cstring */
}
The problem is here:
data->setAdr(data, "asdasd");
Your implementation is :
void CData_setAdr(CData* owner, char* adr) {
owner->adr = adr;
}
So, you overwrite the address of a previously-malloc()ed memory with a pointer to a constant string, so when you do data->del(data);, glibc warns that you are freeing memory that was not allocated, plus the previously allocated memory is lost. Try instead:
void CData_setAdr(CData* owner, char* adr) {
strcpy(owner->adr, adr);
}
Remember to add suitable error-checking, etc!
Here's my code. It works when I comment out the "luetut" variable.
But when I compile as follows, I get segmentation fault when the program should print the variables. What sense does this make? When I try to make a debug build, something totally weird shows up (multiple definition of this and that).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct rakenne
{
int luku;
float liukuluku;
char* mjono;
} Rakenne;
int main(int argc, char *argv[])
{
int luetut = 0;
Rakenne palikka;
// Rakenne palikka, *palikkaosoitin;
// palikkaosoitin = &palikka;
// while(luetut < 1)
// {
printf("Anna luku:\n");
scanf("%d", &palikka.luku);
// } luetut = 0;
// while(luetut < 1)
// {
printf("Anna liukuluku:\n");
scanf("%f", &palikka.liukuluku);
// } luetut = 0;
printf("Anna merkkijono:\n");
scanf("%s", palikka.mjono);
printf("%i\t%.3f\t%s\n", palikka.luku, palikka.liukuluku, palikka.mjono);
return 0;
}
So, is my gcc compiler broken or what could be the problem?
scanf("%s", palikka.mjono);
You didn't make mjono point to anything so writing to it is of course illegal - undefined behavior. Doing something like this leads to erratic behavior: the program "works" or "fails" for no apparent reason.
So, is my gcc compiler broken or what could be the problem
It's rarely constructive to think the tools you are using are the problem.
Expanding on cnicutars answer, the fix would be to allocate some memory for palikka.mjono.
Something like this:
#define SIZE 40 // or whatever you need.
palikka.mjono = malloc( sizeof(char) * SIZE );
Then later don't forget to free that memory:
free( palikka.mjono );
Or if you know what the maximum size of your strings will be, just define your structure as:
typedef struct rakenne
{
int luku;
float liukuluku;
char mjono[SIZE];
} Rakenne;