What is causing my code to be non-deterministic? - c

I might've gone crazy here, but I keep recompiling the exact same code, and get different answers. I'm not using any random values at all. I am strictly staying to floats and 1D arrays (I want to port this to CUDA eventually).
Is it possible on the compiler side that my same code is being redone in a way that makes it not work at all?
I run the .exe by just clicking on it and it runs fine, but when I click "compile and run" (Dev C++ 4.9.9.2) none of my images come out right. ...although sometimes they do.
...any insight on how I fix this? If I can provide any more help please tell me.
Much Appreciated.
Edit:
Here's the block of code that if I comment it out, everything runs sort of right. (Its completely deterministic if I comment this block out)
-this is a electromagnetic simulator, if that helps at all:
//***********************************************************************
// Update HZ in PML regions (hzx,hzy)
//***********************************************************************
boundaryIndex = 0;
for (regionIndex = 1; regionIndex < NUMBEROFREGIONS; regionIndex++) {
xStart = regionData[regionIndex].xStart;
xStop = regionData[regionIndex].xStop ;
yStart = regionData[regionIndex].yStart;
yStop = regionData[regionIndex].yStop ;
for (i = xStart; i < xStop; i++) {
for (j = yStart; j < yStop; j++) {
hzx = hz[i*xSize+j] - hzy[boundaryIndex]; // extract hzx
hzx = dahz[i*xSize+j] * hzx + dbhz[i*xSize+j] * ( ey[i*(xSize+1)+j] - ey[(i+1)*(xSize+1)+j] ); // dahz,dbhz holds dahzx,dbhzx
hzy[boundaryIndex] = dahzy[boundaryIndex] * hzy[boundaryIndex] + dbhzy[boundaryIndex] * ( ex[i*ySize+j+1] - ex[i*ySize+j] );
hz[i*xSize+j] = hzx + hzy[boundaryIndex]; // update hz
boundaryIndex++;
} //jForLoop /
} //iForLoop /
} //
where, NUMBEROFREGIONS is constant (8), Xsize is defined at compile time (128 here).

Well some code examples would help! But this is a classic symptom of un-initialized variables.
You are not setting some important variables (indexes to 0, switches to True etc.) so your program picks up whichever values are hanging around in memory each time you run.
As these are effectively random values you get different results each time.

Is there an indexing error with your simulated two-dimensional array? Is ey supposed to be xSize or xSize+1 wide?
dahz[i*xSize+j] * hzx +
dbhz[i*xSize+j] * ( ey[i*(xSize+1)+j] -
ey[(i+1)*(xSize+1)+j] );
Your index treats 2D array ey as being xSize+1 wide. The code for array ex treats it as being ySize wide.
dbhzy[boundaryIndex] * ( ex[i*ySize+j+1] - ex[i*ySize+j] );

You are potentially invoking undefined behaviour. There are a number of things that are undefined by the C language standard. Some of these cases can be caught by the compiler and you may be issued a diagnostic, others are harder for the compiler to catch. Here is just a few things that have undefined behaviour:
Trying to use the value of an uninitialised variable:
int i;
printf("%d\n", i); // could be anything!
An object is modified more than once between sequence points:
int i = 4;
i = (i += ++i); // Woah, Nelly!
Reading or writing past the end of an allocated memory block:
int *ints = malloc(100 * sizeof (int));
ints[200] = 0; // Oops...
Using printf et. al but providing the wrong format specifiers:
int i = 4;
printf("%llu\n", i);
Converting a value to a signed integer type but the type cannot represent the value (some say this is implementation defined and the C language specification seems ambiguous):
signed short i;
i = 100.0 * 100.0 * 100.0 * 100.0; // probably won't fit
Edit:
Answered before OP provided code.

Are you compiling it in debug mode or release mode? Each one of these have different way how they initialize the heap and memory.

As everybody said without some code of what is wrong we can't help you a lot.
My best gest from what you just explained is that your creating pointers on non allocated memory.
something like this
APointer *aFunction(){
YourData yd = something;//local variable creation
return yd;
}
main(){
APointer *p = aFunction();
}
Here p is a pointer to something that was a local varaible in aFunction and got destroyed as soon as it left the function, this will sometime by PURE LUCK still point to the right data that hasn't been written over, but this memory space will eventual be changed and your pointer will be reading something different completly random.

Related

Unknown cause for Segfault in Gaussian Equation in C

I am currently making a program that approximates the Schroedinger equation, and for my initial conditions, my professor said to begin with a gaussian. The formula I'm using for that is this (apologies, I don't know how to do equations in markdown):
p(x) = ( 1/sqrt(2 * PI) ) * e^( -1/2 * (x-u)^2 / o )
I am starting with u=0 and o=1 for simplicities sake, and so the way I use it in my program is like this:
double gaussian(double x) {
return (1/sqrt(2*M_PI)) * exp((-.5) * pow(x, 2));
}
void initial_conditions(int m, complex *values[], double dx) {
for (size_t i = 0; i < m; i++)
{
values[i]->real = gaussian(i * dx);
}
}
Compiled by: gcc project1.c -lm -o project1
But that produces a segfault every time I have run it. As far as I can tell, it should work, but I am somewhat of a novice to C. I have determined it is specifically that equation that is producing the error by using printf statements to narrow the place of error down, and it always gets to that specific whole formula and return statement and then dies.
Any advice or help would be appreciated.
complex *values[] is weird and unnatural. I can't see the invocation, but I have managed to convince myself that this really should be complex values[].
A complex is far too simple a thing to want to allocate each one individually on the heap; almost always an array of complex would be allocated in a single call to malloc() (or possibly even a stack allocated array by caller).
Proceeding on from the names, I can project with decent confidence the calling code didn't allocate each individual complex in values but just allocated values, and thus the crash is the -> dereference at values[i]->real and values[i] is uninitialized. It's like you want (carrying forward the single array) values[i].real = ... ; values[i].imag = 0;

C string length - is this valid code? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Is this type of expression in C valid (on all compilers)?
If it is, is this good C?
char cloneString (char clone[], char string[], int Length)
{
if(!Length)
Length=64
;
int i = 0
;
while((clone[i++] = string[i]) != '\0', --Length)
;
clone[i] = '\0';
printf("cloneString = %s\n", clone);
};
Would this be better, worse, indifferent?
char *cloneString (char clone[], char string[], int Length)
{
if(!Length)
Length=STRING_LENGTH
;
char *r = clone
;
while
( //(clone[i++] = string[i]) != '\0'
*clone++ = *string++
, --Length
);
*clone = '\0';
return clone = r
;
printf("cloneString = %s\n", clone);
};
Stackoverflow wants me to add more text to this question!
Okay! I'm concerned about
a.) expressions such as c==(a=b)
b.) performance between indexing vs pointer
Any comments?
Thanks so much.
Yes, it's syntactically valid on all compilers (though semantically valid on none), and no, it isn't considered good C. Most developers will agree that the comma operator is a bad thing, and most developers will generally agree that a single line of code should do only one specific thing. The while loop does a whole four and has undefined behavior:
it increments i;
it assigns string[i] to clone[i++]; (undefined behavior: you should use i only once in a statement that increments/decrements it)
it checks that string[i] isn't 0 (but discards the result of the comparison);
it decrements Length, and terminates the loop if Length == 0 after being decremented.
Not to mention that assuming that Length is 64 if it wasn't provided is a terrible idea and leaves plenty of room for more undefined behavior that can easily be exploited to crash or hack the program.
I see that you wrote it yourself and that you're concerned about performance, and this is apparently the reason you're sticking everything together. Don't. Code made short by squeezing statements together isn't faster than code longer because the statements haven't been squeezed together. It still does the same number of things. In your case, you're introducing bugs by squeezing things together.
The code has Undefined Behavior:
The expression
(clone[i++] = string[i])
both modifies and accesses the object i from two different subexpressions in an unsequenced way, which is not allowed. A compiler might use the old value of i in string[i], or might use the new value of i, or might do something entirely different and unexpected.
Simple answer no.
Why return char and the function has no return statement?
Why 64?
I assume that the two arrays are of length Length - Add documentation to say this.
Why the ; on a new line and not after the statement?
...
Ok so I decided to evolve my comments into an actual answer. Although this doesn’t address the specific piece of code in your question, it answers the underlying issue and I think you will find it illuminating as you can use this — let’s call it guide — on your general programming.
What I advocate, especially if you are just learning programming is to focus on readability instead of small gimmicks that you think or was told that improve speed / performance.
Let’s take a simple example. The idiomatic way to iterate through a vector in C (not in C++) is using indexing:
int i;
for (i = 0; i < size; ++i) {
v[i] = /* code */;
}
I was told when I started programming that v[i] is actually computed as *(v + i) so in generated assembler this is broken down (please note that this discussion is simplified):
multiply i with sizeof(int)
add that result to the address of v
access the element at this computed address
So basically you have 3 operations.
Let’s compare this with accessing via pointers:
int *p;
for (p = v; p != v + size; ++p) {
*p = /*..*/;
}
This has the advantage that *p actually expands to just one instruction:
access the element at the address p.
2 extra instructions don’t seam much but if your program spends most of it’s time in this loop (either extremely large size or multiple calls to (the functions containing this) loop) you realise that the second version makes your program almost 3 times faster. That is a lot. So if you are like me when I started, you will choose the second variant. Don’t!
So the first version has readability (you explicitly describe that you access the i-th element of vector v), the second one uses a gimmick in detriment of readability (you say that you access a memory location). Now this might not be the best example for unreadable code, but the principle is valid.
So why do I tell you to use the first version: until you have a firm grasp on concepts like cache, branching, induction variables (and a lot more) and how they apply in real world compilers and programs performance, you should stay clear of these gimmicks and rely on the compiler to do the optimizations. They are very smart and will generate the same code for both variants (with optimization enabled of course). So the second variant actually differs just by readability and is identical performance-wise with the first.
Another example:
const char * str = "Some string"
int i;
// variant 1:
for (i = 0; i < strlen(str); ++i) {
// code
}
// variant 2:
int l = strlen(str);
for (i = 0; i < l; ++i) {
// code
}
The natural way would be to write the first variant. You might think that the second improves performance because you call the function strlen on each iteration of the loop. And you know that getting the length of a string means iterating through all the string until you reach the end. So basically a call to strlen means adding an inner loop. Ouch that has to slow the program down. Not necessarily: the compiler can optimize the call out because it always produces the same result. Actually you can do harm as you introduce a new variable which will have to be assigned a different register from a very limited registry pool (a little extreme example, but nevertheless a point is to be made here).
Don’t spend your energy on things like this until much later.
Let me show you something else that will illustrate further more that any assumptions that you make about performance will be most likely be false and misleading (I am not trying to tell you that you are a bad programmer — far from it — just that as you learn, you should invest your energy in something else than performance):
Let’s multiply two matrices:
for (k = 0; k < n; ++k) {
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
r[i][j] += a[i][k] * b[k][j];
}
}
}
versus
for (k = 0; k < n; ++k) {
for (j = 0; j < n; ++j) {
for (i = 0; i < n; ++i) {
r[i][j] += a[i][k] * b[k][j];
}
}
}
The only difference between the two is the order the operations get executed. They are the exact same operations (number, kind and operands), just in a different order. The result is equivalent (addition is commutative) so on paper they should take the EXACT amount of time to execute. In practice, even with optimizations enable (some very smart compilers can however reorder the loops) the second example can be up to 2-3 times slower than the first. And even the first variant is still a long long way from being optimal (in regards to speed).
So basic point: worry about UB as the other answers show you, don’t worry about performance at this stage.
The second block of code is better.
The line
printf("cloneString = %s\n", clone);
there will never get executed since there a return statement before that.
To make your code a bit more readable, change
while
(
*clone++ = *string++
, --Length
);
to
while ( Length > 0 )
{
*clone++ = *string++;
--Length;
}
This is probably a better approach to your problem:
#include <stdio.h>
#include <string.h>
void cloneString(char *clone, char *string)
{
for (int i = 0; i != strlen(string); i++)
clone[i] = string[i];
printf("Clone string: %s\n", clone);
}
That been said, there's already a standard function to to that:
strncpy(const char *dest, const char *source, int n)
dest is the destination string, and source is the string that must be copied. This function will copy a maximum of n characters.
So, your code will be:
#include <stdio.h>
#include <string.h>
void cloneString(char *clone, char *string)
{
strncpy(clone, string, strlen(string));
printf("Clone string: %s\n", clone);
}

What's the best way to set all elements of array to a value?

I have an array of ints and I'd like to set all values in the array to 'x' everytime a function is called.
I've looked at memset but that would only work for an array of bytes I think.
I could do the obvious for loop, but I'm guessing there is a standard lib function out there that will accomplish this better. Anyone know?
Just loop it, pretty much. Or memset to 0, if you know the value is zero (similar for other values for which you have knowledge of the bit representation). There won't be a standard lib solution, since the standard lib can't know of particular user types.
If you're on an x86 system, you can use some assembly for this. For instance, in gcc:
__asm__(
"rep stosb"
: "=a"('x'), "=c"(count), "=D"(array)
);
Should do the trick.
rep stosb takes the value in AL and assigns it to consecutive memory locations pointed to by ES:EDI. The number of the locations is specified in ECX.
As an aside, in recent processors Intel has made many efforts to improve the performance of MOVSB and STOSB, so this is a good way to go about it.
In addition to memset and looping (which are both O(n) time), it can be actually done in O(1) - but at the cost of triple the amount of memory, and more expensive look ups later on.
This article describes how it can be done.
The idea is to maintain additional stack (logically, implemented as array+ pointer to top) and array, the additional array will indicate when it was first initialized (a number from 0 to n) and the stack will indicate which elements were already modified.
When you access array[i], if stack[additionalArray[i]] == i && i < top the value of the array is array[i]. Otherwise - it is the "initialized" value.
When doing array[i] = x, if it was not initialized yet (as seen before), you should set additionalArray[i] = stack[top] and increase top.
This results in O(1) initialization, but as said it requires additional memory and each access is more expansive.
Below logic will helps you.
...
int a[100] = {0};
int b = 5;
memset_ex(a, 100, &b, sizeof(int));
...
memset_ex(void *buf, int buf_size, void *value, int size_of_type)
{
int i = 0;
for(i = 0; i <= (buf_size - size_of_type); i +=size_of_type)
{
memcpy((buf + i), value, size_of_type);
}
}

Is this the correct way to return an array of structs from a function?

As the title says (and suggests), I'm new to C and I'm trying to return an arbitrary sized array of structs from a function. I chose to use malloc, as someone on the internet, whose cleverer than me, pointed out that unless I allocate to the heap, the array will be destroyed when points_on_circle finishes executing, and a useless pointer will be returned.
The code I'm presenting used to work, but now I'm calling the function more and more in my code, I'm getting a runtime error ./main: free(): invalid next size (normal): 0x0a00e380. I'm guessing this is down to my hacked-together implementation of arrays/pointers.
I'm not calling free as of yet, as many of the arrays I'm building will need to persist throughout the life of the program (I will be adding free() calls to the remainder!).
xy* points_on_circle(int amount, float radius)
{
xy* array = malloc(sizeof(xy) * amount);
float space = (PI * 2) / amount;
while (amount-- >= 0) {
float theta = space * amount;
array[amount].x = sin(theta) * radius;
array[amount].y = cos(theta) * radius;
}
return array;
}
My ground-breaking xy struct is defined as follows:
typedef struct { float x; float y; } xy;
And an example of how I'm calling the function is as follows:
xy * outer_points = points_on_circle(360, 5.0);
for(;i<360;i++) {
//outer_points[i].x
//outer_points[i].y
}
A pointer in the right direction would be appreciated.
Allocating memory in one function and freeing it in another is fraught with peril.
I would allocate the memory and pass it (the memory buffer) to the function with a parameter indicating how many structures are allowed to be written to the buffer.
I've seen APIs where there are two functions, one to get the memory required and then another to actually get the data after the memory has been allocated.
[Edit] Found an example:
http://msdn.microsoft.com/en-us/library/ms647005%28VS.85%29.aspx
I would say that this program design is fundamentally flawed. First of all, logically a function which is doing calculations has nothing to do with memory allocation, those are two different things. Second, unless the function that allocates memory and the one that frees it belong to the same program module, the design is bad and you will likely get memory leaks. Instead, leave allocation to the caller.
The code also contains various dangerous practice. Avoid using -- and ++ operators as part of complex expressions, it is a very common cause for bugs. Your code looks as if it has a fatal bug and is writing out of bounds on the array, just because you are mixing -- with other operators. There is never any reason to do so in the C language, so don't do it.
Another dangerous practice is the reliance on C's implicit type conversions from ints to float (balancing, aka "the usual arithmetic conversions"). What is "PI" in this code? Is it an int, float or double? The outcome of the code will vary depending on this.
Here is what I propose instead (not tested):
void get_points_on_circle (xy* buffer, size_t items, float radius)
{
float space = (PI * 2.0f) / items;
float theta;
signed int i;
for(i=items-1; i>=0; i--)
{
theta = space * i;
buffer[i].x = sin(theta) * radius;
buffer[i].y = cos(theta) * radius;
}
}
EDIT: You are returning the array correctly, but ...
Consider you're making an array with 1 element
xy *outer_points = points_on_circle(1, 5.0);
What happens inside the function?
Let's check ...
xy* array = malloc(sizeof(xy) * amount);
allocate space for 1 element. OK!
while (amount-- >= 0) {
1 is greater or equal to 0 so the loop executes (and amount gets decreased)
after setting array[0] you return to the top of the loop
while (amount-- >= 0) {
0 is greater or equal to 0 so the loop executes (and amount gets decreased)
You're now trying to set array[-1], which is invalid because the index refers to an area outside of the array.
I think this:
while (amount-- >= 0 ) {
should be:
while ( --amount >= 0 ) {
Consider the case where amount is zero initially.
You're doing the right thing as far as I'm concerned, provided of course your callers are free'ing the results.
Some people prefer to have the memory allocation and freeing responsibility in the same place (for symmetry), i.e. outside your function. In this case you would pass a pre-allocated xy* as a parameter and return the size of the buffer if the pointer was null:
int requiredSpace = points_on_circle(10, 10, NULL);
xy* myArray = (xy*)malloc(requiredSpace);
points_on_circle(10, 10, myArray);
free(myArray);
You are iterating over one element to much.
You should use the goes down to zero operator instead:
while ( amount --> 0) {
...
}
Allocating memory in one function and freeing it in the other is like giving a gun to a four year old. You shoudn't do that.
While your decision to count down amount and use while instead of using a temp value saved a few memory cycles, it is more conceptually confusing. Especially in a case where the maths are taking all the time here, you only save fractions.
But that is not the reason why you should waste minor amounts of time. This question is the reason: you've wasted hours! This applies to even the most experienced and smartest programmers. The mistakes are just more complicated and beyond the scope of a stackoverflow answer! In other words, the Peter Principle applies to coding too.
Don't make the mistake as you gain experience that you can get away with taking these kinds of risks to save a cycle or two. That is why McConnell in Code Complete lists Humility as a positive programmer attribute.
Here's the solution you probably thought of to start with:
xy* points_on_circle(int amount, float radius)
{
xy* array = malloc(sizeof(xy) * amount);
float space = (PI * 2) / amount;
int index;
for (index=0;index<amount;index++) {
float theta = space * index;
array[index].x = sin(theta) * radius;
array[index].y = cos(theta) * radius;
}
return array;
}
If you need speed, a tiny thing you can do is put theta outside the loop set to 0 and add 'space' each time since + is bound to be cheaper than * in floating point.
speed it up 10x or more?
If you need serious speed, this tip from answers.com will give you an improvement of 10x if you do it right:
By Pythagoream's theorem, x2 + y2 is
radius2. It is then simple to solve
for x or y, given the other along with
radius. You also do not need to
compute for the whole circle - you can
compute for one quadrant, and generate
the other three quadrants by symmetry.
You generation loop would, for
example, simply iterate from origin to
radius as x by delta x, generating y,
and reflecting that in the other three
quadrants. You can also compute for
one half of a quadrant, and use both
symmetry and reflection to generate
the other seven half quadrants.
When I was 12 I thought I was hot stuff drawing a circle using sin and cos in graphics 8 on my atari 800. My cousin Marty (when as of late worked form Microsoft robotics) erased my program and implemented the above solution, using only addition in the loop if I remember right, and draw the same circle in 4 seconds instead of a minute! Had I not been baptized I would have bowed down in worship. Too bad I don't have the code handy but I'd bet a little googling would bring it up. Anybody?

STM32 printf and RTC

* UPDATE *
Here is what I found. Whenever I had that function in there it wouldn't actually make the code lock up. It would actually make the read RTC I²C function very slow to execute, but the code would still run properly, but I had to wait a really long time to get past every time I read the RTC.
So there is an alarm interrupt for the RTC and this was triggering other I²C interactions inside the ISR, so it looks like it was trying to do two I²C communications at the same time, therefore slowing down the process. I removed the functions in the ISR and it's working now. I will keep investigating.
I am having this problem when programming an STM32F103 microcontroller using IAR 5.40. I have this function that if I try to printf a local variable it causes the code to freeze at another point way before it even gets to that function in question.
What could possibly be causing this?
This is the function:
u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
char bTmpSms[3] = {0};
itoa(bSmsIndex, bTmpSms, 10); // Converts the smsindex into a string
printf("index = %s\n", bTmpSms); // This printf caused the code to get stuck in the RTC // byte read function!
GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
return 1;
}
I tried this as well and this does not cause the lock I experienced:
u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
char bTmpSms[3] = {0};
itoa(bSmsIndex, bTmpSms, 10);
printf("index = 2\n");
GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
return 1;
}
There is no optimization enabled whatsoever and the code gets stuck when trying to read a byte out of my I²C RTC, but as soon as I remove this printf("index = %s\n", bTmpSms); or use this one instead printf("index = 2\n"); then everything is happy. Any ideas?
The bSmsIndex will never be more than 30 actually and even then the lock up happens wayyyy before this function gets called.
char bTmpSms[3] only has space for "99". If your bSmsIndex is 100 or greater, you will be trying to write to memory that doesn't belong to you.
Edit after the update
I don't have a reference to itoa on my local machine, but I found this one ( http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/ ). According to that reference, the destination array MUST BE LONG ENOUGH FOR ANY POSSIBLE VALUE. Check your documentation: your specific itoa might be different.
Or use sprintf, snprintf, or some function described by the Standard.
Some ideas:
If itoa() is not properly NUL-terminating the string, then the call to printf may result in the machine looking for the NUL forever.
pmg has a very good point.
Also, consider what type the first argument to itoa() is. If it's signed and you're passing in an unsigned integer, then you may be getting an unexpected minus sign in bTmpSms. Try using sprintf() instead.
The change in code is moving the rest of your code around in memory. My guess is that some other part of the code, not listed here, is bashing some random location; in the first case that location contains something critical, in the second case it does not.
These are the worst kinds of problems to track down*. Good luck.
*Maybe not the worst - it could be worse if it were a race condition between multiple threads that only manifested itself once a week. Still not my favorite kind of bug.
It seems that if I don't initialize the variable bTmpSms to something the problem occurs.
I also realized that it is not the printf that is the problem. It is the itoa function. It got me to check that even though I didn't think that was the problem, when I commented the itoa function then the whole code worked.
So I ended up doing this:
u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
char bTmpSms[4] = "aaa"; // I still need to find out why this is !!!
itoa(bSmsIndex, bTmpSms, 10); // Converts the smsindex into a string
printf("index = %s\n", bTmpSms); // This printf caused the code to get stuck in the RTC // byte read function!
GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
return 1;
}
This is the itoa function I got:
char itoa(int value, char* result, int base)
{
// Check that the base if valid
if (base < 2 || base > 36) {
*result = '\0';
return 0;
}
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do
{
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsr
qponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while (value);
// Apply negative sign
if (tmp_value < 0)
*ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr)
{
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return 1;
}
What's the value of bSmsIndex you're trying to print?
If it's greater than 99 then you're overrunning the bTmpSms array.
If that doesn't help, then use IAR's pretty good debugger - I'd drop into the assembly window at the point where printf() is being called and single step until things went into the weeds. That'll probably make clear what the problem is.
Or as a quick-n-dirty troubleshoot, try sizing the array to something large (maybe 8) and see what happens.
What's the value of bSmsIndex?
If more than 99 it will be three digits when converted to a string. When zero terminated, it will be four characters, but you've allocated only three to bTmpSms so the null may get overwritten and the printf will try to print whatever is after bTmpSms until the next null. That could access anything, really.
Try to disassemble this area with index = 2 vs. index = %s.

Resources