objective-c I can't understand why using of sprintf lead program to crash - objective-c

-(void)InitWithPwd:(char *)pPwd
{
char szResult[17];
//generate md5 checksum
CC_MD5(pPwd, strlen(pPwd),&szResult[0]);
szResult[16] = 0;
m_csPasswordHash[0]=0;
for(int i = 0;i < 16;i++)
{
char sz[3] = {'\0'};
//crash in blow row. The first pass is ok. The third pass crash.
//I can't understand.
sprintf(&sz[0],"%2.2x",szResult[i]);
strcat(m_csPasswordHash,sz);
}
m_csPasswordHash[32] = 0;
printf("pass:%s\n",m_csPasswordHash);
m_ucPacketType = 1;
}
I want to get the md5 of the password. But above code crash again and again. I can't understand why.

Your buffer (sz) is too small, causing sprintf() to generate a buffer overflow which leads to undefined behavior, in your case a crash.
Note that szResult[1] might be a negative value when viewed as an int (which happens when passing a char-type value to sprintf()), which can cause sprintf() to disregard your field width and precision directives in order to format the full value.
Here is an example showing this problem. The example code is written in C, but that shouldn't matter for this case.
This solves the problem by making sure the incoming data is considered unsigned:
sprintf(sz, "%02x", (unsigned char) szResult[i]);

Related

Remove an Array element [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
So im trying to code a function to remove an element from an Array.for some reason i'm getting no errors but still does not print the result i need. i think the problem is in the function or data type declaration.
#import <Foundation/Foundation.h>
void deleteArray(char stra[ ], char ElementToRemove);
int main(int argc, const char * argv[]) {
#autoreleasepool {
char str[100];
printf("Please Enter Array Elements\n");
scanf("%s",&str);
deleteArray(str, "a");
printf("%s",&str);
}
return 0;
}
void deleteArray(char stra[ ], char ElementToRemove)
{
int NumberOfElements = sizeof(stra);
int ElementPos;
for (int i = 0; i >= NumberOfElements;i++)
{
if (ElementToRemove == stra [i])
{
ElementPos = i;
}
}
for (int SecondCounter = ElementPos; SecondCounter >= NumberOfElements;SecondCounter++ )
{
stra[SecondCounter] = stra[SecondCounter - 1];
}
}
There are many issues with your code, let's see them one by one.
When you pass an array to a function, it decays to a pointer to the first element of the array. So, sizeof in the deleteArray() function is not doing what you think it's doing there.
You can use strlen() instead to get the length of a char array. However, please note, this does not count the terminating null, anyways, and you need to move that one, too, to make the end of the modified array.
Then, in the for loop,
for (int i = 0; i >= NumberOfElements;i++) //false always....
is wrong. I believe what you want is
for (int i = 0; i < NumberOfElements;i++)
After that, regarding the call to the function should be
deleteArray(str, 'a'); // 'a' is a char
instead of
deleteArray(str, "a"); // "a" denotes a string
Next, in the main() function, remove the & from the argument to printf(). It should look like
printf("%s",str);
Also, to ensure safety from buffer overflow, you should make yourscanf() to look like
scanf("%99s",str);
If you need dynamically sized arrays, I recommend making them the last flexible array member (that wikipage has an example) of some (growable) struct and keep the size of that array in its containing struct ....
If you want to have array features, such as add, delete, move and so on, use linked lists. Linked lists are using pointers, so you can represent an array using them. This way it is possible to delete an element, move it or add a new one.
When declaring an array in c, you declare it fixed size. In your case, if you want not to use pointers and lists, you have to copy array elements to a new one, excluding the unneeded.

Something weird in for loop speed

here is a part of my program code:
int test;
for(uint i = 0; i < 1700; i++) {
test++;
}
the whole program takes 0.5 seconds to finish, but when I change it to:
int test[1];
for(uint i = 0; i < 1700; i++) {
test[0]++;
}
it will takes 3.5 seconds! and when I change the int to double, it will gets very worse:
double test;
for(uint i = 0; i < 1700; i++) {
test++;
}
it will takes about 18 seconds to finish !!!
I have to increase an int array element and a double variable in my real for loop, and it will takes about 30 seconds!
What's happening here?! Why should it takes that much time for just an increment?!
I know a floating point data type like double has different structure from a fixed point data type like int, but is it the only cause for such a big different time? and what about the second example which is also an int array element?!
Thanks
You have answered your question yourself.
float (double) operations are different from integer ones. Even if you just add 1.0f.
Your second example takes longer than the first one just because you added some pointer refernces. An array in C is -bottom down- not much different from a pointer to the first element. Accessing any element, even the first one, would cause the machine code to load the starting address of the array multiply the index (0 in this case) with the length of each member (4 or whatever bytes int has) and add that (0) to the pointer. Then it has to dereference the pointer, meaning to acutally load the value at that very address. Add one and write back the result.
A smart modern compiler should optimize this a bit. When you want to avoid this optimization, then modify the code a bit and don`t use a constant for the index.
I never tried that with a modern objective-c compiler. But I guess that this code would take much loger than 3.5s to run:
int test[2];
int index = 0;
for(uint i = 0; i < 1700; i++) {
test[index]++;
}
If that does not make much of a change then try this:
-(void)foo:(int)index {
int test[2];
for(uint i = 0; i < 1700; i++) {
test[index]++;
}
}
and then call foo:0;
Give it a try and let us know :)

EXC_BAD_ACCESS in attempt to rewrite NSString ComponentsSeparatedByString:

I'm writing an objective-C program to deal with trajectories of Biomolecules with XCODE 4.3.1 and ARC. I need to read PDB files, i.e. parse large quantities of text formatted data. I'm very disappointed by NSString inefficiency and was trying to write a C-equivalent of componentsSeparatedByString:. The algorithm works just fine with NSString and NSMutableArrays, but i'm having a hard time using char* and char**.
Unfortunately, I'm getting an EXC_BAD_ACCESS error. The strange thing is that i get the error for i=68103 and j=68049 (does these number ring a bell for you ?), which means it worked for some time before crashing. The error is "static" (always block at the same (i,j) numbers). The array seems to work just fine(NSLog on its values before crash).
As it seems, I'm not very experienced with C-code and the subtlety behind pointers, but I would definitely be glad to hear your suggestions to make it work ! Thanks !
Heres the code :
+(char**) componentsSeparedByNewLineCEQUIV:(const char*)aChar:(int*)numWord
{ // char* aChar : my file, is typically 3 millions characters
int j=-1; //Last non space character
int i; //Scanned character
int len=strlen(aChar);
char** stringArray=malloc((*numWord)*sizeof(char*));
for (i=0;i<len; i++)
{ if (aChar[i]==10)
{
if ( j!=-1)
{
char* buffer2=malloc(i-j+1);
strcpy(buffer2, strndup(aChar+j, i-j));
stringArray[i]=malloc(sizeof(char)*strlen(buffer2)+1); //EXC_BAD_ACCESS HERE
strcpy(stringArray[i], buffer2);
}
j=-1;
}
else if (j==-1)
{j=i;}
}
if (j!=-1)
{ char* buffer2=malloc(i-j+1);
strcpy(buffer2, strndup(aChar+j, i-j));
stringArray[i]=malloc(strlen(buffer2)+1);
strcpy(stringArray[i], buffer2);
}
return stringArray;
}
You're probably not the first person to have this problem :)
Why not just use strtok?
PS What analysis showed that NSString was your problem?
I don't know why the error is at the line above of where it should be.However you are copying a string that is not allocated.
stringArray[i] is not allocated when you copy on it buffer2, allocate it:
if ( j!=-1)
{
char* buffer2=malloc(i-j+1);
strcpy(buffer2, strndup(aChar+j, i-j));
stringArray[i]=malloc(sizeof(char)*strlen(buffer2)+1); //EXC_BAD_ACCESS HERE
stringArray[i]=(char*)malloc( (strlen(buffer2)+1)*sizeof(char)); // Allocate the string
strcpy(stringArray[i], buffer2);
}
First: if Im not totaly wrong, but i think you are consuming at least 4-times as much memory as you need to:
You are using malloc for creating buffer2 and also using strndup for getting the wanted chars. strndup does exactly what you want, but in one step. char* buffer2 = strndup(aChar+j, i-j) should be your first step. Even worse in the next two line you are essential doing the same again. So i think what you are really want is stringArray[i] = strndup(aChar+j, i-j). To look at memory Problems: all the functions use errno to indicate memory allocating failure.
Second: Your functions does not return the number of components, so your stringArray may contain some garbage without knowing.
Third: strlen is expensive and you do not need it, just use for(int i = 0; aChar[i] != '\0'; i++)
Update for everyone who might be interested : this is a working version, using strtok which can be useful, although i'm still interested in response on my code.
This code have been tested 5 times faster (125ms vs 581ms) than [astring componentsSeparatedByString:#"\n"] ...
+(char**)componentsSeparatedByNewLine:(const char*)aChar:(int*)numWord
{
int i;
int j=0;
int len = strlen(aChar);
*numWord=1;
for (i=0;i<len; i++)
{
if (aChar[i]==10) *numWord=*numWord+1; //change 10 for any other character (ASCII for space)
}
char** stringArray=malloc((*numWord)*sizeof(char*));
char* pch;
char* aChar2=malloc(len+1);
strcpy(aChar2,aChar);
pch = strtok(aChar2,"\n");
while (pch != NULL)
{
stringArray[j]=(char*)malloc( (strlen(pch)+1)*sizeof(char));
strcpy(stringArray[j], pch);
//NSLog(#"%s",stringArray[j]);
j=j+1;
pch = strtok (NULL, "\n");
}
return stringArray;
}

Realloc not expanding my array

I'm having trouble implementing realloc in a very basic way.
I'm trying to expand the region of memory at **ret, which is pointing to an array of structs
with ret = realloc(ret, newsize); and based on my debug strings I know newsize is correctly increasing over the course of the loop (going from the original size of 4 to 8 to 12 etc.), but when I do sizeof(ptr) it's still returning the original size of 4, and the things I'm trying to place into the newly allocated space can't be found (I think I've narrowed it down to realloc() which is why I'm formatting the question like this)
I can post the function in it's entirety if the problem isn't immediately evident to you, I'm just trying to not "cheat" with my homework too much (the code is kind of messy right now anyway, with heavy use of printf() for debug).
[EDIT] Alright, so based on your answers I'm failing at debugging my code, so I guess I'll post the whole function so you can tell me more about what I'm doing wrong.
(You can ignore the printf()'s since most of that is debug that isn't even working)
Booking **bookingSelectPaid(Booking **booking) {
Booking **ret = malloc(sizeof(Booking*));
printf("Initial address of ret = %p\n", ret);
size_t i = 0;
int numOfPaid = 0;
while (booking[i] != NULL)
{
if (booking[i]->paid == 1)
{
printf("Paying customer! sizeof(Booking*) = %d\n", (int)sizeof(Booking*));
++numOfPaid;
size_t newsize = sizeof(Booking*) * (numOfPaid + 1);
printf("Newsize = %d\n", (int)newsize);
Booking **temp = realloc(NULL, (size_t)newsize);
if (temp != NULL)
printf("Expansion success! => %p sizeof(new pointer) = %d ret = %p\n", temp, (int)sizeof(temp), ret);
ret = realloc(ret, newsize);
ret[i] = booking[i];
ret[i+1] = NULL;
}
++i;
printf("Sizeof(ret) = %d numOfPaid = %d\n", (int)sizeof(ret), numOfPaid);
}
return ret; }
[EDIT2] --> http://pastebin.com/xjzUBmPg
[EDIT3] Just to be clear, the printf's, the temp pointer and things of that nature are debug, and not part of the intended functionality. The line that is puzzling me is either the one with realloc(ret, newsize); or ret[i] = booking[i]
Basically I know for sure that booking contains a table of structs that ends in NULL, and I'm trying to bring the ones that have a specific value set to 1 (paid) onto the new table, which is what my main() is trying to get from this function... So where am I going wrong?
I think the problem here is that your sizeof(ptr) only returns the size of the pointer, which will depend on your architecture (you say 4, so that would mean you're running a 32-bit system).
If you allocate memory dynamically, you have to keep track of its size yourself.
Because sizeof(ptr) returns the size of the pointer, not the allocated size
Yep, sizeof(ptr) is a constant. As the other answer says, depends on the architecture. On a 32 bit architecture it will be 4 and on a 64 bit architecture it will be 8. If you need more help with questions like that this homework help web site can be great for you.
Good luck.

printf(), fprintf(), wprintf() and NSlog() won't print on XCode

I'm doing a small app for evaluating and analyzing transfer functions. As boring as the subject might seem to some, I want it to at least look extra cool and pro and awesome etc... So:
Step 1: Gimme teh coefficients! [A bunch of numbers]
Step 2: I'll write the polynomial with its superscripts. [The bunch of numbers in a string]
So, I write a little C parser to just print the polynomial with a decent format, for that I require a wchar_t string that I concatenate on the fly. After the string is complete I quickly try printing it on the console to check everything is ok and keep going. Easy right? Welp, I ain't that lucky...
wchar_t *polynomial_description( double *polyArray, char size, char var ){
wchar_t *descriptionString, temp[100];
int len, counter = 0;
SUPERSCRIPT superscript;
descriptionString = (wchar_t *) malloc(sizeof(wchar_t) * 2);
descriptionString[0] = '\0';
while( counter < size ){
superscript = polynomial_utilities_superscript( size - counter );
len = swprintf(temp, 100, L"%2.2f%c%c +", polyArray[counter], var, superscript);
printf("temp size: %d\n", len);
descriptionString = (wchar_t *) realloc(descriptionString, sizeof(wchar_t) * (wcslen(descriptionString) + len + 1) );
wcscat(descriptionString, temp);
counter++;
}
//fflush(stdout); //Already tried this
len = wprintf(L"%ls\n", descriptionString);
len = printf("%ls**\n", descriptionString);
len = fprintf(stdout, "%ls*\n", descriptionString);
len = printf("FFS!! Print something!");
return descriptionString;
}
During the run we can see temp size: 8 printed the expected number of times ONLY WHILE DEBUGGING, if I run the program I get an arbitrary number of prints each run. But after that, as the title states, wprintf, printf and fprintf don't print anything, yet len does change its size after each call.
In the caller function, (application:(UIApplication *)application didFinishLaunchingWithOptions:, while testing) I put an NSLog to print the return string, and I dont get ANYTHING not even the Log part.
What's happening? I'm at a complete loss.
Im on XCode 4.2 by the way.
What's the return value from printf/wprintf in the case where you think it's not printing anything? It should be returning either -1 in the case of a failure or 1 or more, since if successful, it should always print at least the newline character after the description string.
If it's returning 1 or more, is the newline getting printed? Have you tried piping the output of your program to a hex dumper such as hexdump -C or xxd(1)?
If it's returning -1, what is the value of errno?
If it turns out that printf is failing with the error EILSEQ, then what's quite likely happening is that your string contains some non-ASCII characters in it, since those cause wcstombs(3) to fail in the default C locale. In that case, the solution is to use setlocale(3) to switch into a UTF-8 locale when your program starts up:
int main(int argc, char **argv)
{
// Run "locale -a" in the Terminal to get a list of all valid locales
setlocale(LC_ALL, "en_US.UTF-8");
...
}