Usage of dynamic memory management functions causing crashes [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.
I've recently uptaken rewriting argument handling code I began to create, and I've added utilization of dynamic memory management functions (malloc, realloc, free), but after adding such I am getting strange crashes when I attempt to execute an example.
The following is output from my program:
charles#draton-generico:~/Documents/C/C89/SDL_Work/2D-game-base$ ./game-base-02-alt-2 --l
Successfully exited argument catching loop.
==>Continuing execution.
* glibc detected ./game-base-02-alt-2: realloc(): invalid next size: 0x000000000157c010 **
After outputting this much it just hangs.
The following is my code:
/*
* CREATED BY: Charles Edwin Swain 3rd
* DATE OF PROJECT BEGINNING: 28/1/2013
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
int* bse = malloc(3 + 5 + 5 + argc);
if (bse == NULL)
{
if (fprintf(stderr, "Call to malloc failed, bse = NULL.\n==>Will now exit.\n") <= 0) exit(-2);
exit(-1);
}
*(bse + 0) = 0;
while (*(bse + 0) < (3 + 5 + 5 + argc))
{
*(bse + *(bse + 0)) = 0;
*(bse + 0) = *(bse + 0) + 1;
}
*(bse + 0) = 0;
*(bse + 1) = -1;
/*THIS DETERMINES THE SIZE OF THE LARGEST ARGV CHARACTER STRING.*/
while (*(bse + 3) < argc)
{
while (*(bse + 4) != -1)
{
if (argv[*(bse + 3)][*(bse + 4)] == '\0')
{
if ((*(bse + 4) + 1) > *(bse + 5)) *(bse + 5) = *(bse + 4) + 1;
*(bse + 4) = -1;
}
else if (*(bse + 4) == 32766)
{
*(bse + 3 + 5 + 5 + *(bse + 3)) = 1;
*(bse + 4) = -1;
}
else *(bse + 4) = *(bse + 4) + 1;
}
*(bse + 3) = *(bse + 3) + 1;
*(bse + 4) = 0;
}
*(bse + 3) = 0;
/*ENSURING THAT SPACE FOR RETREIVED ARGV CHARACTER STRINGS IS AT LEAST THE SIZE OF THE LARGEST CHECKED FOR SPECIFIC STRING ON LINE BELOW.*/
if (*(bse + 5) < 10) *(bse + 5) = 10;
/*THIS IS (IN SOME CASES WAS) THE BIG ARGV CATCHING LOOP.*/
/*ERASED CONTENTS OF, AM REWRITING CODE.*/
while (*(bse + 3) < argc)
{
*(bse + 3) = argc;
}
if (fprintf(stdout, "Successfully exited argument catching loop.\n==>Continuing execution.\n") <= 0)
{
while ((*(bse + 1) <= 0)&&(*(bse + 2) < 50))
{
*(bse + 1) = fprintf(stderr, "A function (fprintf) failed when outputting a notification informing of having 'properly' left the argument catching loop.\n==>Will now exit.\n");
*(bse + 2) = *(bse + 2) + 1;
}
free(bse);
exit(-1);
}
/*SET DEFAULTS HERE*/
bse = realloc(bse, 3);
if (bse == NULL)
{
if (fprintf(stderr, "Call to realloc failed, bse = NULL.\n==>Will now exit.\n") <= 0) exit(-2);
exit(-1);
}
/*END OF CODE.*/
free(bse);
exit(0);
}
I'd love to turn this into a learning experience.

malloc() and realloc() have no idea about what kind of data type you're going to store in the memory pointed to by the returned pointers. So they just allocate some bytes - and they don't magically multiply their arguments by sizeof(int). So what you want is:
int *bse = malloc((3 + 5 + 5 + argc) * sizeof(*bse));
and the alike with realloc().

Related

the time complexity of my code is O(n+m)?

My code is below :
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int* new = (int*)malloc(sizeof(int) * (nums1Size+nums2Size));
int i = 0;
int count1 = 0;
int count2 = 0;
if(nums1Size+nums2Size == 1){
if(nums1Size == 1)
return *nums1;
else
return *nums2;
}
else if(nums1Size == 0){
if((nums2Size & 0x1) == 0)
return (double)(nums2[nums2Size/2-1]+nums2[nums2Size/2])/2;
else
return (double)nums2[nums2Size/2];
}
else if(nums2Size == 0){
if((nums1Size & 0x1) == 0)
return (double)(nums1[nums1Size/2-1]+nums1[nums1Size/2])/2;
else
return (double)nums1[nums1Size/2];
}
while(i != (nums1Size+nums2Size))
{
if((nums1[count1 == nums1Size ? count1-1:count1] > nums2[count2 == nums2Size ? count2-1:count2]
&& (count2) != nums2Size)
|| (count1) == nums1Size)
{
*(new+i) = *(nums2+count2);
count2++;
}
else{
*(new+i) = *(nums1+count1);
count1++;
}
i++;
}
if(((nums1Size+nums2Size) & 0x1) == 0){
return (double)(new[(nums1Size+nums2Size)/2 - 1] + new[(nums1Size+nums2Size)/2]) / 2;
}
else
return (double)new[(nums1Size+nums2Size)/2];
}
And below is the submissions's runtime distribution on Leetcode :
The Question is, even if there are a lot of submitted codes with O(log (m+n)) in C but I think my code's Time complexity is O(m+n). so it doesn't make sense that my code is top 2% on Leetcode according to the distribution graph. of course linear is faster than log to a small amount of inputs but the test-cases are enough big to get beaten by O(log (m+n)). I don't know why my code get passed with that rate.
will greatly appreciate your comments!
From my top comment: You allocate new at the start of the function. If any of the "early escape" return statements are executed, you'll leak memory.
So do I have to put free() in every return statement? or how can i fix my code?
Don't do the malloc until after the top block of early escapes.
And, do the free at the bottom. To do this, you'll need an extra variable to hold the return value so you can safely do the free(new) (e.g. double retval;)
Side note: It's usually cleaner to replace (e.g.) *(new + i) with new[i]. Also, holding the code to <= 80 chars / line is also a good style.
Here's one way to fix your code [please pardon the gratuitous style cleanup]:
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
int *new;
int i;
int count1 = 0;
int count2 = 0;
double retval;
if (nums1Size + nums2Size == 1) {
if (nums1Size == 1)
return *nums1;
else
return *nums2;
}
if (nums1Size == 0) {
if ((nums2Size & 0x1) == 0)
return (double) (nums2[nums2Size / 2 - 1] +
nums2[nums2Size / 2]) / 2;
else
return nums2[nums2Size / 2];
}
if (nums2Size == 0) {
if ((nums1Size & 0x1) == 0)
return (double) (nums1[nums1Size / 2 - 1] +
nums1[nums1Size / 2]) / 2;
else
return (double) nums1[nums1Size / 2];
}
// allocate this only when you're sure you'll use it
new = malloc(sizeof(int) * (nums1Size + nums2Size));
for (i = 0; i != (nums1Size + nums2Size); ++i) {
if ((nums1[count1 == nums1Size ? count1 - 1 : count1] >
nums2[count2 == nums2Size ? count2 - 1 : count2] &&
(count2) != nums2Size)
|| (count1) == nums1Size) {
new[i] = nums2[count2];
count2++;
}
else {
new[i] = nums1[count1];
count1++;
}
}
if (((nums1Size + nums2Size) & 0x1) == 0) {
retval = (double) (new[(nums1Size + nums2Size) / 2 - 1] +
new[(nums1Size + nums2Size) / 2]) / 2;
}
else
retval = (double) new[(nums1Size + nums2Size) / 2];
free(new);
return retval;
}
But, personally, I dislike multiple return statements in a function. It's harder to debug [using gdb] because you'd have to set a breakpoint on each return.
Here's a version that uses a do { ... } while (0); as a "once through" loop that allows us to eliminate the if/else "ladder" logic [which I also personally dislike] and have only a single return at the bottom. YMMV ...
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
int *new = NULL;
int i = 0;
int count1 = 0;
int count2 = 0;
double retval;
do {
if (nums1Size + nums2Size == 1) {
if (nums1Size == 1)
retval = *nums1;
else
retval = *nums2;
break;
}
if (nums1Size == 0) {
if ((nums2Size & 0x1) == 0)
retval = (double) (nums2[nums2Size / 2 - 1] +
nums2[nums2Size / 2]) / 2;
else
retval = nums2[nums2Size / 2];
break;
}
if (nums2Size == 0) {
if ((nums1Size & 0x1) == 0)
retval = (double) (nums1[nums1Size / 2 - 1] +
nums1[nums1Size / 2]) / 2;
else
retval = (double) nums1[nums1Size / 2];
break;
}
// allocate this only when you're sure you'll use it
new = malloc(sizeof(int) * (nums1Size + nums2Size));
for (; i != (nums1Size + nums2Size); ++i) {
if ((nums1[count1 == nums1Size ? count1 - 1 : count1] >
nums2[count2 == nums2Size ? count2 - 1 : count2] &&
(count2) != nums2Size)
|| (count1) == nums1Size) {
new[i] = nums2[count2];
count2++;
}
else {
new[i] = nums1[count1];
count1++;
}
}
if (((nums1Size + nums2Size) & 0x1) == 0) {
retval = (double) (new[(nums1Size + nums2Size) / 2 - 1] +
new[(nums1Size + nums2Size) / 2]) / 2;
}
else
retval = (double) new[(nums1Size + nums2Size) / 2];
} while (0);
if (new != NULL)
free(new);
return retval;
}
UPDATE:
thanks! I understood. your code is more clear than mine for real!. but what do you think about the performance between them? ( if/else and do{...}while(0)). because if we assume the compiler would work as we generally expect, if/else is faster than if if which is in do{...} in the revised code. thanks a lot again!
Actually, if we disassemble both versions [compiled with -O2], the do/while version is 4 assembly instructions shorter.
But, in order to tune it, you have to measure it.
The optimizer will pretty much make them similar.
The main bulk of the time of the function is spent in the for loop, which is the same for both. The speed of the loop dwarfs any extra overhead of do/while which might be an assembler instruction or two [but, again the do/while has fewer instructions].
So, tuning/optimizing the prolog/epilog code of the function isn't [usually] worth it. Speeding up the loop is.
To tune/optimize, either do profiling to determine where the code spends the most amount of time [or for something this simple, it's obviously the loop], or add timestamping and get elapsed time on the function [or various subparts].
As I mentioned, it's hard to add a breakpoint for a function that has multiple return statements.
Also, sometimes you can't attach a debugger. Or, it's difficult to find a meaningful place to put a breakpoint. For example, if you have a program that runs fine for (e.g.) days, and then aborts after (e.g.) 63 hours, you may need to do internal benchmarking and printf style debugging:
#ifdef DEBUG
#define dbgprint(_fmt) \
do { \
printf(_fmt); \
} while (0)
#else
#define dbgprint(_fmt) \
do { \
} while (0)
#endif
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
double retval;
dbgprint("findMedianSortedArrays: ENTER nums1Size=%d nums2Size=%d\n",
nums1Size,nums2Size);
// ... the code
dbgprint("findMediaSortedArrays: EXIT retval=%g\n",retval);
return retval;
}
It's much easier to insert the debug print statements with the second version.
BTW, I do this sort of thing all the time. And, one of my fortes is fast code and performance improvement [as I do a lot of realtime coding].

How to convert char string into hex value

I have one situation where i am receiving characters serially, byte by byte in USB Tx mode.
Now I'm stuck at where I am receiving 7 and a and my objective is to create 0x7a data.
Please provide me some workaround.
void converttohex(int recsize) {
BYTE ccount = 0;
//BYTE *recptr = (BYTE*)calloc(CommOP_Rx.bDataLength, sizeof(BYTE));
*recptr = 88;
*(recptr + 1) = 16;
*(recptr + 2) = 1;
*(recptr + 3) = 224;
*(recptr + 4) = 1;
for (xp = 12, s = 5; xp < (CommOP_Rx.bDataLength - 4); xp++,s++) {
if (xp == 12) {
for (xp = 12; (*(recimage + xp)) != ','; xp++)
ccount++;
if (ccount == 1) {
xp = 12;
xq = (*(recimage + xp) - 48);
*(recptr+s) = xq;
xp++;
} else
if (ccount == 2) {
xp = 12;
xq = (*(recimage + xp) - 48) * 10;
xw = (*(recimage + (++xp)) - 48);
*(recptr + s) = xq + xw;
xp++;
} else
if (ccount == 3) {
xp = 12;
xq = (*(recimage + xp) - 48) * 100;
xw = (*(recimage + (++xp)) - 48) * 10;
xe = (*(recimage + (++xp)) - 48);
*(recptr+s) = xq + xw + xe;
xp++;
}
}
xp++;
if (((*(recimage + xp)) == 'a') || ((*(recimage + (++xp))) == 'a')) {
--xp;
if (((*(recimage + xp)) == 'a')) {
xq = (*(recimage + xp) - 48) * 10;
} else
xq = (*(recimage + xp) - 48);
xw = 'a';
*(recptr + s) = xq +xw;
}
xq = (*(recimage + xp) - 48) * 10;
xw = (*(recimage + (++xp)) - 48);
*(recptr + s) = xq + xw;
}
for (xp = 0; xp < (CommOP_Rx.bDataLength - 4); xp++) {
*(recimage + xp) = *(recptr + xp);
}
Basically here i am sampling some data, which is the array of image in hex, and storing it in my MCU array. But here i have implemented that when i will receive a two consecutive data in which which is an Integer 0-9, then i am subtracting 48 into it as all the bytes are in character encoding, upto this it is working fine, but after receiving A-F of hex, lets suppose i have received '7' & 'a' and it has to be value=0x7a , thus i need this conversion help!!
Store it in a null-terminated string and read from it.
// Assume N is a big number
char str[N] = "7A";
int ret;
sscanf(str, "%x", &ret);
printf("%d", ret); // Output: 122
To do it repetitively, let the program construct this array:
int i = 0;
while (read_data(&ch)){
// Assume ch is in "0123456789ABCDEFabcdef"
str[i++] = ch;
}
str[i] = 0;
// Now parse it
int ret;
sscanf(str, "%x", &ret);
You can store the hex digits in an array of char, null terminate this array an use sscanf() or strtol() to convert the string to a number.
Your code seems quite complicated for me to understand. Just giving a glimpse of what can be done to get hexadecimal value based on your question and not based on your code. Sorry for that.
If you process the two inputs as string then the below approach will suite.
char num1[] = "7";
char num2[] = "a";
char num[10];
strcpy (num, num1);
strcat (num, num2);
Now num has 7a as hexadecimal string
If you have the two inputs as integers then this logic will work
int num1,num2,num3;
num1=0x7;
num2=0xa;
num3=(num1<<4)|(num2);
sprintf(str,"0x%x",num3);

how to make 2 stage for loop statement from 1 stage for loop in c?

I'd like to make 2 stage for loop statment from 1 stage in the c.
//gray rgb
for (unsigned int i = 0; i < x * y; i++)
{
*(buff2 + i * 3 + 0) = data_[i];
*(buff2 + i * 3 + 1) = data_[i];
*(buff2 + i * 3 + 2) = data_[i];
}
But actually I can't get think how do I can make 2 stage.
Can you give a any hint?
Hope it would help you:-
for(i=0;i<x;i++)
{
for(j=0;j<y;j++)
{
*(buff2 + i*y + j) = data_[i*y+j]
}
}

Problems comparing integers to hardcoded values in a dll called from VBA

I am about to transfer a project I have written in Applescript and Objective C to Excel/VBA/dll. I have started with the Objective C functions that I want to place in a dll and call via VBA.
First of all, I am a statistician who managed to build the original Mac program (a statistical tool that have been very handy to me) through equal amounts of luck, trial and error and perseverance. Please take that into account (also if the answer is embarrassingly obvious). I have used this (minus the 64 bit part) as starting point for the dll: https://sites.google.com/site/jrlhost/links/excelcdll
The Objective C is C with a thin dusting of special Obejctive C code to have it talk with Applescript and the rest of the project so in theory it should be easy to make dlls written in C from it.
But I have already problems with the tiniest of all functions. I am sure it can be done more effectively but right now I need to know WHY it doesn´t work if I am ever going to be able to transfer the much larger functions from Objective C to C.
Here is the C code I am trying:
int _stdcall game(int *games, int *gameskifte)
{
if (*games == 0){
if (*gameskifte == 1) return *games + 1;
else return *games + 2;}
else{
if (*games < 3){
if (*gameskifte == 2) return *games + 2;
else return *games + 4;}
else{
if (*gameskifte == 2) return *games + 3;
else return games + 5;
}
}
return 0;
}
Here is what the code is supposed to do:
If games = 0 and gameskifte = 1, return 1
if games = 0 (and by default gameskifte is not 1), return 2
If games < 3 and gameskifte = 1, return games + 2
If games < 3 (and by default gameshift is not 1), return games + 4
If games > 2 and gameskifte = 1, return games + 3
If games > 2 (and by default gameshift is not 1), return games + 5
What it does is ignore the value of gameshift and ALWAYS returns games + 4
I tried to change a few things...
This code (where all compares are "<" but the result should be the same)
int _stdcall game(int *games, int *gameskifte)
{
if (*games < 1){
if (*gameskifte < 2) return *games + 1;
else return *games + 2;}
else{
if (*games < 3){
if (*gameskifte < 2) return *games + 2;
else return *games + 4;}
else{
if (*gameskifte < 2) return *games + 3;
else return games + 5;
}
}
return 0;
}
Always gives me games + 1
And this (where all compares are ">" and where the result should NOT nessesary be the same as above):
int _stdcall game(int *games, int *gameskifte)
{
if (*games > 1){
if (*gameskifte > 2) return *games + 1;
else return *games + 2;}
else{
if (*games > 3){
if (*gameskifte > 2) return *games + 2;
else return *games + 4;}
else{
if (*gameskifte > 2) return *games + 3;
else return games + 5;
}
}
return 0;
}
always gives me games + 5
So when doing the return calculation it knows the value of *games but when comparing *games to another hardcoded value it throws a false when doing a direct or ">" compare and a positive when doing any "<" compare no matter if the value is lower or higher.
The rest of the project is
A def file: defFile.def:
LIBRARY ”minfil”
EXPORTS
game=game
The VBA:
Private Declare Function game Lib "c:\users\musholm\documents\visual studio 2013\Projects\mitprojekt\Debug\mitprojekt.dll" (ByRef games As Integer, ByRef gameskifte As Integer) As Integer
Function game1(games As Integer, gamesskifte As Integer) As Integer
game1 = game(games, gamesskifte)
End Function
The Excel function is =game1(x,y)
And finally the original objective c I am trying to recreate in C:
- (NSNumber *)game:(NSNumber *)games gamechange:(NSNumber *)gameskifte
{
int gamesab = [games intValue];
int gameskifteab = [gameskifte intValue];
int gamesud = 0;
if (gamesab == 0){
if (gameskifteab == 1) gamesud=1;
else gamesud=2;}
else{
if (gamesab<3){
if (gameskifteab==1)gamesud=gamesab+2;
else gamesud=gamesab+4;}
else{
if (gameskifteab==1)gamesud=gamesab+3;
else gamesud=gamesab+5;
}
}
return [NSNumber numberWithInt:gamesud];
}
VBA's Integer corresponds to C's short.
You want the function parameters and the return value As Long in VBA.
Also you are missing a * in else return games + 5;. Although you don't need * in the first place, you should remove them all and redeclare the function parameters in VBA with ByVal.

Parse a URL in C

I am trying to parse several elements of a URL in C.
This is a prototype of a URL:
ftp://[< name>:< pass>#]< domain>/< url>";
The problem is that certain elements aren't being saved correctly, for example I try to save the ftp:// in here ftp[6]. However, when I print it I get something like this ftp:/d#. Which should not even be possible since the array does not have enough space for this.
int main()
{
char ftp[6];
char *name;
char *pass;
char *domain;
char *url;
char *var = "ftp://[coiso:pass#]teste/umgrandeurl";
int x;
int size_name;
int size_pass;
int size_domain;
int size_url;
int flag = 0;
for (x = 0; x < strlen(var); x++) {
if (x == 6) {
strncpy(ftp, var, 6);
if (strcmp(ftp, "ftp://") != 0) {
}
}
if (var[x] == ':' && x > 3) {
size_name = x - 7;
name = (char *)malloc(size_name + 1);
strncpy(name, &var[7], size_name);
}
if (var[x] == '#') {
size_pass = x - (8 + size_name);
pass = (char *)malloc(size_pass + 1);
strncpy(pass, &var[8 + size_name], size_pass);
}
if (var[x] == '/' && x > 6 && flag == 0) {
flag = 1;
size_domain = x - (10 + size_pass + size_name);
domain = (char *)malloc(size_domain + 1);
strncpy(domain, &var[10 + size_pass + size_name], size_domain);
}
if (x == strlen(var) - 1) {
size_url = x - (10 + size_pass + size_name + size_domain);
url = domain = (char *)malloc(size_url + 1);
strncpy(url, &var[11 + size_pass + size_name + size_domain], size_url);
printf("%d", size_url);
}
}
return 0;
}
EDIT: Well the same thing happens to me in the pass but it isn't because of the null char.
Instead of building your own url parser try UriParse
from the man page:
The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the
first n bytes of src, the string placed in dest will not be null-terminated
size_url=x-(10+size_pass+size_name+size_domain);
url=domain =(char*) malloc( size_url+1);
strncpy(url,&var[11+size_pass+size_name+size_domain],size_url+1);
^^
... and similar for the other sizes / strncpy()s.

Resources