I am a beginner in C and as I was trying to make a simple snake game, I stumbled upon the problem of value change in pointers when used in another function. I used pointers in order to grow my snake and I used 3 of them. Granted this might be a really noobish algorithm for a snake game but I feel like I am almost there but I cannot figure out what went wrong. I have used 3 pointes for the snake itself, the x coordinate of each part of the snake and also the y. I might as well just post a part of my code.
#include<stdio.h>
#include<dos.h>
#include<conio.h>
printer(int *forgoodness,int *y,char *lang,int tx,int ty, int *x)
{
int h=*forgoodness-1,g=0;
The value changes in here, somehow the x copies 6 values of the y.
/* for(;g<15;g++)
{
printf("%i",x[g]);
}*/
for(;h>=0;h--)
{
gotoxy(x[h],y[h]);
printf("%c",lang[h]);
}
gotoxy(tx,ty);
printf(" ");
}
main()
{
int transferx=1,x=1,transfery=1,ch,game=0,dir;
int *transx, *transy, *numel;
int tempsx,g=0,tempsy,forex,j=0,*totalel;
char *snake;
int *snakey, *snakex;
If I explicitly assign values it works well but I cannot grow my snake using this:
//int snakex[15]={26,27,28,29,30,31,32,33,34,35,36,37,38,39,40};
//int snakey[15]={13,13,13,13,13,13,13,13,13,13,13,13,13,13,13};
clrscr();
*totalel=0;
*numel=14;
forex=26;
snake= "***************";
This is what I did, and I checked the values before the function printer runs and the values are fine.
for(;j<15;j++)
{
snakey[j]=13;
snakex[j]=forex;
*totalel=j;
forex++;
}
printer(numel,snakey,snake,transferx,transfery,snakex);
I hope that you can help me on this. Cheers.
Maybe attempt to rewrite a bit of your code... ideally using less pointers. Based on the code I see, it looks as if you're feeding values into random pointers. That's pretty dangerous.
For instance, doing these two lines in a row is bad:
int *num;
*num = 9;
The reason is because num is just a pointer to memory... and it isn't currently pointing to anything valid yet. The number 9 is attempting to be stored in some random location. You need to allocate some memory for num to point to, or point it to the address of another variable (a non-pointer integer). I think maybe you're not quite grasping the concepts of pointers just yet. But don't worry, it takes a little time.
You should be able to write your game without using any pointers at all, and maybe just use a fixed array for now like someone else had mentioned. Then do a bit more reading up on how pointers work and take another stab at it. I'm sure you'll get it!
But for now, try to revisit the problem with a new set of data and come back to us with what you've done so we can try to help out further. :)
Cool that you are working with pointers! But as you can see, they can be a little tricky. You have to remember that pointers are like the address of a mailbox; they can tell where something is, but they cannot (in of themselves) HOLD ANYTHING. The can just point to something that does. So every pointer you declare has to point to a real thing (like an int or an array element or an array) before it can be used or assigned to. Otherwise to are shoving values into random memory areas which causes crashes. This seems to be the main problem you are having.
int *ptr;
int value;
ptr = &value;
*ptr = 10;
// value now is 10
Related
I'm a beginner in C .... I have a little code:
#include <stdio.h>
#include <string.h>
int main(){
char str1[100];
char str2[100];
char str3[100];
char str4[100];
puts(str1)
puts(str2);
puts(str3);
puts(str4);
return 0;
}
I got result
2
èý(
‘Q]wØ„ÃîþÿÿÿÀ"bwd&bw
I don't know why my array does not empty from the begin. And I have to set first element to "\0" to clear content of array. Can anyone explain for me. Thank a lot.
In C, local variables are not initialized automatically if you don't assign values to them. Here your arrays are uninitialized, which means they may contain garbage after their creation.
Yes, you need to explicitly set it to be "empty" like:
char str[100];
str[0] = '\0';
// Now you have an empty string of zero length.
assert(strlen(str) == 0);
// But the size is still 100.
printf ("%d", sizeof(str));
Alternatively, you can create an empty string(character array) during the initialization. It has the same size and length as the example above.
char str[100] = "";
As for why it doesn't automatically zero the string, it's because that would be costly to do so, and C generally doesn't do costly things that you don't explicitly tell it to do. At a minimum, it would have to set the first element of every array to zero,and there are plenty of occasions where you wouldn't want to or need to initialize the array like this. If C always did this for you, then you'd always have that useless overhead that you couldn't get rid of.
As a general rule, C doesn't do anything in the background that you don't explicitly tell it to do, so when you ask for an array, it just gives you an array, and doesn't touch the contents unless you tell it to. It can create a little bit more work for the programmer, but with the benefit of more finely-grained control over exactly what the computer is doing.
Some people would consider that it's a good programming practice to always initialize your variables anyway, and to forget about this kind of tiny cost, and a lot of the time they'll have a good point, but C is deliberately a very flexible and low-level language, and it just doesn't force you to do things like this.
one is getting old when one says "In my days...". But nevertheless, "in my days", people were instructed to first declare variables, and directly afterward initialise variables.
In your case, you can do both together and even more thoroughly in one statement.
The solution of Eric Z is the correct one, that I would also use when I'm working the C-way. But to be complete for you, what age_pan describes is that Java inherently does te following:
#include <stdio.h>
int main(int argc, const char * argv[])
{
char str1[100] = { 0 };
char str2[100] = { 0 };
char str3[100] = { 0 };
char str4[100] = { 0 };
puts(str1);
puts(str2);
puts(str3);
puts(str4);
return 0;
}
The difference is that in the solution of Eric Z only the first character is set to 0, which means that you create a zero length zero terminated string. The Java method (shown in the code above) initialises every little byte to 0.
There are pro's and con's to the Java initialisation. It leads to sloppy programming (some call it easier programming) and it takes time if you don't need initialising. On the other hand, I know very little people that need te extra milliseconds that are lost by the initialisation.
Is it necessary to declare variables above the code, and to initialise them? Certainly not. Is it useful? It most certainly is. It avoids all kinds of errors that take a lot of time to debug.
By the way, you are missing a ; after puts(str1) :-)
Kind regards,
PB
I don't think you had any trouble if the array doesn't start with "empty". In C, the variables start with random values. Unlike in Java, when you declare a variable, the JVM will initiate it by default.
I would like to know, is that possible to initialize the structure1 by structure2.
I am new to the concept of casting too.
The output of this code has to be zero. Please guide. Thanks!
#include<stdio.h>
typedef struct student
{
int roll_id[10];
int name_id[10];
int postn;
} student;
typedef struct exams
{
int subject[10];
int area;
}exams;
int main()
{
exams e= { {0} };
student *pptr= (student*)&e;
printf (" %d\n", pptr->name_id[9]);
return 0;
}
Analogy is simple:
You buy an Apple and pretend it is an Orange.
As long as you eat it as something eatable you can eat it, but If you bite in to it expecting to get orange juice you will end up disappointed.
Replace Apple & Orange by your two structures and you by compiler.
Structure is nothing but a block of memory which is usually occupied by different data types.
The compiler implementation may add padding bytes between these types except for the first type in the structure.
Since the first type of your both structures is same(an array of 10 integers). Pretending the structure exam as of other type, student will work but if you try to access any other data type other than the first type it will result in Undefined Behavior.
Undefined Behavior is what you are getting in your code.
Bottom line:
You cannot do this.
First of all, in your code you are not initializing structure1 by structure2, but merely disguising pointer to structure2 as a pointer to structure1.
exams structure instance apparently (let alone weird alignment settings) takes less memory than student instance. Accessing pptr->name_id[9] can very well result in reading past the area dedicated to e. Now it all depends upon your compiler, your computer and so on.. meaning that it is better avoid delving into such details for one's sake.
The output of this code has to be zero
Perhaps it is if you are reading from unallocated stack area (past e) and in your setup stack is filled with zeroes before handing it over to the running thread.
Please read more in your C book about casting and automatic memories and instances and pointers. There is really so much to tell to right your code. You would be better off asking more specific questions after you've studied on the topic more. Good luck
I've written some code that doesn't want to work, and after much thought I've decided that the cause of all my trouble is a loop that is trying to copy strings to an array, which is a component of a structure, pointed to by a pointer passed to the function.
This isn't exactly my code, but whatever is making this not work is also making my code not work:
typedef struct {
int A[100];
} thing;
this something vaguely like the structure I'm using.
Then within the main function:
thing *s;
int i;
for (i=0;i<5;i++) {
s->A[i]=i;
}
So, this doesn't work. Much to my dismay and confusion, however, this does:
thing *s;
s->A[0]=0;
s->A[1]=1;
s->A[2]=2;
s->A[3]=3;
s->A[4]=4;
Concerning this, I am at a loss, and have spent much time indeed trying to find a solution for myself. I know I'm missing something here, I just hope it's not obvious
That's undefined behavior; there is no object behind that pointer -- the result could be anything. Undefined behavior can appear to work, or it can fail in very mysterious ways.
You could approach it like this:
thing th;
thing* s = &th;
...now 's' points to a 'thing' -- specifically, 'th'.
i was just trying to check the default value of int and char when not initialised in c.
my problem is that i get two different outputs when i use clrscr() to clear the screen between 2 runs.could someone explain this behavior to me?
here is the code
void main()
{
int i;
char c;
printf("%d %c",i,c);
}
output: 0
void main()
{
int i;
char c;
clrscr();
printf("%d %c",i,c);
}
output:-29542 //some garbage value which is what i was expecting in both cases
You shouldn't be expecting anything in particular. The values are uninitialized, i.e.: can be anything.
Why the garbage value in the first case differs from the garbage value in the second case? Who knows? Different memory map, different execution paths - different garbage.
I think it always give some garbage value ..you can't determine the behavior... :-/
In case of your code, you will get garbage values, but if the integer varibale was declared globally then its default value will be 0 for sure in C.
I mentioned this because question's title was-"Default values of int when not initialized in c".
Actually zeros were garbage as well. After you add clrscr(); you changed stack so you did to garbage.
In managed code, there are default values, usually 0 or equivalent.
In the unmanaged world, there is no default value. When the memory is allocated, the system just tells you "You can write here is you want, but I don't know what mess the previous program let behind".
This behaviour is seen for some people as bad since their program can be unpredictable for some obscure reasons, but it is also a way to be able to optimize as much as we can memory management, think of large buffer allocation which when allocated would be filled with 0s, and then filled with actual data. You get twice the performance in unmanaged code!
OK, I hope I explain this one correctly.
I have a struct:
typedef struct _MyData
{
char Data[256];
int Index;
} MyData;
Now, I run into a problem. Most of the time MyData.Data is OK with 256, but in some cases I need to expand the amount of chars it can hold to different sizes.
I can't use a pointer.
Is there any way to resize Data at run time? How?
Code is appreciated.
EDIT 1:
While I am very thankful for all the comments, the "maybe try this..." or "do that", or "what you are dong is wrong..." comments are not helping. Code is the help here. Please, if you know the answer post the code.
Please note that:
I cannot use pointers. Please don't try to figure out why, I just can't.
The struct is being injected into another program's memory that's why no pointers can be used.
Sorry for being a bit rough here but I asked the question here because I already tried all the different approaches that thought might work.
Again, I am looking for code. At this point I am not interested in "might work..." or " have you considered this..."
Thank you and my apologies again.
EDIT 2
Why was this set as answered?
You can use a flexible array member
typedef struct _MyData
{
int Index;
char Data[];
} MyData;
So that you can then allocate the right amount of space
MyData *d = malloc(sizeof *d + sizeof(char[100]));
d->Data[0..99] = ...;
Later, you can free, and allocate another chunk of memory and make a pointer to MyData point to it, at which time you will have more / less elements in the flexible array member (realloc). Note that you will have to save the length somewhere, too.
In Pre-C99 times, there isn't a flexible array member: char Data[] is simply regarded as an array with incomplete type, and the compiler would moan about that. Here i recommend you two possible ways out there
Using a pointer: char *Data and make it point to the allocated memory. This won't be as convenient as using the embedded array, because you will possibly need to have two allocations: One for the struct, and one for the memory pointed to by the pointer. You can also have the struct allocated on the stack instead, if the situation in your program allows this.
Using a char Data[1] instead, but treat it as if it were bigger, so that it overlays the whole allocated object. This is formally undefined behavior, but is a common technique, so it's probably safe to use with your compiler.
The problem here is your statement "I can't use a pointer". You will have to, and it will make everything much easier. Hey, realloc even copies your existing data, what do you want more?
So why do you think you can't use a pointer? Better try to fix that.
You would re-arrange the structure like that
typedef struct _MyData
{
int Index;
char Data[256];
} MyData;
And allocate instances with malloc/realloc like that:
my_data = (MyData*) malloc ( sizeof(MyData) + extra_space_needed );
This is an ugly approach and I would not recommend it (I would use pointers), but is an answer to your question how to do it without a pointer.
A limitation is that it allows for only one variable size member per struct, and has to be at the end.
Let me sum up two important points I see in this thread:
The structure is used to interact between two programs through some IPC mechanism
The destination program cannot be changed
You cannot therefore change that structure in any way, because the destination program is stuck trying to read it as currently defined. I'm afraid you are stuck.
You can try to find ways to get the equivalent behavior, or find some evil hack to force the destination program to read a new structure (e.g., modifying the binary offsets in the executable). That's all pretty application specific so I can't give much better guidance than that.
You might consider writing a third program to act as an interface between the two. It can take the "long" messages and do something with them, and pass the "short" messages onward to the old program. You can inject that in between the IPC mechanisms fairly easily.
You may be able to do this like this, without allocating a pointer for the array:
typedef struct _MyData
{
int Index;
char Data[1];
} MyData;
Later, you allocate like this:
int bcount = 256;
MyData *foo;
foo = (MyData *)malloc(sizeof(*foo) + bcount);
realloc:
int newbcount = 512;
MyData *resized_foo;
resized_foo = realloc((void *)foo, sizeof(*foo) + newbcount);
It looks like from what you're saying that you definitely have to keep MyData as a static block of data. In which case I think the only option open to you is to somehow (optionally) chain these data structures together in a way that can be re-assembled be the other process.
You'd need and additional member in MyData, eg.
typedef struct _MyData
{
int Sequence;
char Data[256];
int Index;
} MyData;
Where Sequence identifies the descending sequence in which to re-assemble the data (a sequence number of zero would indicate the final data buffer).
The problem is in the way you're putting the question. Don't think about C semantics: instead, think like a hacker. Explain exactly how you are currently getting your data into the other process at the right time, and also how the other program knows where the data begins and ends. Is the other program expecting a null-terminated string? If you declare your struct with a char[300] does the other program crash?
You see, when you say "passing data" to the other program, you might be [a] tricking the other process into copying what you put in front of it, [b] tricking the other program into letting you overwrite its normally 'private' memory, or [c] some other approach. No matter which is the case, if the other program can take your larger data, there is a way to get it to them.
I find KIV's trick quite usable. Though, I would suggest investigating the pointer issue first.
If you look at the malloc implementations
(check this IBM article, Listing 5: Pseudo-code for the main allocator),
When you allocate, the memory manager allocates a control header and
then free space following it based on your requested size.
This is very much like saying,
typedef struct _MyData
{
int size;
char Data[1]; // we are going to break the array-bound up-to size length
} MyData;
Now, your problem is,
How do you pass such a (mis-sized?) structure to this other process?
That brings us the the question,
How does the other process figure out the size of this data?
I would expect a length field as part of the communication.
If you have all that, whats wrong with passing a pointer to the other process?
Will the other process identify the difference between a pointer to a
structure and that to a allocated memory?
You cant reacolate manualy.
You can do some tricks wich i was uning when i was working aon simple data holding sistem. (very simple filesystem).
typedef struct
{
int index ;
char x[250];
} data_ztorage_250_char;
typedef struct
{
int index;
char x[1000];
} data_ztorage_1000_char;
int main(void)
{
char just_raw_data[sizeof(data_ztorage_1000_char)];
data_ztorage_1000_char* big_struct;
data_ztorage_250_char* small_struct;
big_struct = (data_ztorage_1000_char*)big_struct; //now you have bigg struct
// notice that upper line is same as writing
// big_struct = (data_ztorage_1000_char*)(&just_raw_data[0]);
small_struct = (data_ztorage_250_char*)just_raw_data;//now you have small struct
//both structs starts at same locations and they share same memory
//addresing data is
small_struct -> index = 250;
}
You don't state what the Index value is for.
As I understand it you are passing data to another program using the structure shown.
Is there a reason why you can't break your data to send into chunks of 256bytes and then set the index value accordingly? e.g.
Data is 512 bytes so you send one struct with the first 256 bytes and index=0, then another with the next 256 bytes in your array and Index=1.
How about a really, really simple solution? Could you do:
typedef struct _MyData
{
char Data[1024];
int Index;
} MyData;
I have a feeling I know your response will be "No, because the other program I don't have control over expects 256 bytes"... And if that is indeed your answer to my answer, then my answer becomes: this is impossible.