This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char *dd,aaa[500];
strcpy(aaa,"test 1");
dd=aaa;
printf("1. %s\n",dd);
strcpy(aaa,"test 2");
printf("2. %s\n",dd);
system("pause");
return 0;
}
When i have changed aaa variable by test 2 string, dd also changes, why?
It could be great if you said what you are trying to do in order for others to put your code into perspective.
Now you seem to have not understood well how pointers work. Since your code isn't really easy to read, the answer will be general.
Pointers 'hold' addresses to memory. If you have pointer ptr1 pointing towards memory block A and pointer ptr2 pointing towards ptr1, if you change ptr1, naturally ptr2 will experience the same changes. In your first block of code, you seem not to understand why someVar changes after otherVar changes. To make more explicit what #dmp has pointed out, you have told you program ( the operating system is managing memory for your program ) that someVar will point towards the value held in otherVar[0]. Now when otherVar[0] changes, someVar will change because that is how pointers are supposed to work, it is called to dereference a pointer - when you request the value of what the pointer points to - and you'll notice that things changed pr ptr2. So, please reread about pointers again.
In your second block of code, I don't know what you trying to accomplish but whatever it is, it will SEGFAULT. That is so because again, you haven't understood the relationship between pointers, arrays and how dynamic memory allocation works. For example, in the splittext function you have this line:
wchar_t *arr[2],*loc = wcsstr(stri, del), buf[DEFAULT_BUFLEN];
Right there: you telling the operating system to check the value at the 3rd cell of *arr while you haven't allocated memory for it. Also, when allocating memory, remember:
If you want to allocate memory for char to get a string your pointer will have to be a pointer towards char like this:
char* my_string = malloc( 256*sizeof(char))
Now you want to get memory allocated to pointers towards say variables of type FILE*.
If you write FILE** my_files = malloc( NUMBER_OF_FILES*sizeof(FILE)) it will get you into trouble. Rather write :
FILE** my_files = malloc( NUMBER_OF_FILES*sizeof(FILE*))
This is with regards to how you allocated memory for say arr.
Also don't cast the return value of malloc. It will hide many errors the compiler could have caught!
To sum up, first try to learn about pointers before moving on to a bit advanced uses of pointers, arrays and memory allocation; second you can't put incorrect code ( you will know it is incorrect either it doesn't compile or just crash ) and tell others : "hey look at that variable, that is where my problem is." Try to do more research into the question, try learning what tools can assist - a debugger in this case - and that will be improve the quality of your question. Third and last, if English is not your first language, you can mention it and others will be willing to assist in reformulating your question.
Hope you will do better next time!
UPDATE
After edit by OP, the question now is clearer and the OP's problem is about pointers.
dd's value changes because:
aaa is a pointer like this: char aaa[500] is equivalent to char* aaa = malloc(500*sizeof(char)). Now when you dd=aaa, you told the compiler that dd will point to the same memory address as does aaa. So every time you modify aaa dd gets modified because they point to the same thing in memory.
If that wasn't clear, try to reread the definition of a pointer.
What you ask is not clear, however, pointers in C are passed by value (there is a copy of the pointer pointing to the same location). If you dereference a pointer and change the value pointed to, the caller will see the change.
A quick pointer lesson should clear it up:
What happens on this line?
char *dd = aaa;
You've created a pointer to a character allocation called dd and pointed it to the memory address that aaa is stored at.
aaa's address is on the stack and static (you created it implicitly with your aaa[500]).
Now, when you put data into aaa, aaa's location in memory does not change, simply the data stored at that position in memory. When you try to print out the 'contents' of aaa, you're getting the characters stored at that point in memory. When you copy new data into aaa, the position in memory still remains the same, and thus dd is still pointing to the same memory space as aaa does.
My apologies if that's no clearer than anyone else's...
Related
This question is aimed at improving my understanding of
what I can and cannot do with pointers when allocating and freeing:
The bellow code is not meant to run, but just set up a situation for the questions bellow.
char *var1 = calloc(8,sizeof(char));
char **var2 = calloc(3,sizeof(char*));
var1 = "01234567";
var1[2] = '\0';
var1[5] = '\0';
//var1 = [0][1][\0][3][4][\0][6][7]
var2[0] = var1[0];
var2[1] = var1[3];
var2[2] = var1[6];
free(var1);
free(var2);
given the following snippet
1: is it ok to write to a location after the \0 if you know the size you allocated.
2: Can I do what I did with var2 , if it points to a block that another pointer is pointing at?
3: are the calls to free ok? or will free die due to the \0 located throughout var1.
I printed out all the variables after free, and only the ones up to the first null got freed (changed to null or other weird and normal looking characters). Is that ok?
4: Any other stuff you wish to point out that is completely wrong and should be avoided.
Thank you very much.
Ok, let's just just recap what you have done here:
char *var1 = calloc(8,sizeof(char));
char **var2 = calloc(3,sizeof(char*));
So var1 is (a pointer to) a block of 8 chars, all set to zero \0.
And var2 is (a pointer to) a block of 3 pointers, all set to NULL.
So now it's the program's memory, it can do whatever it wants with it.
To answer your questions specifically ~
It's quite normal to write characters around inside your char block. It's a common programming pattern to parse string buffers by writing a \0 after a section of text to use everyday C string operations on it, but then point to the next character after the added \0 and continue parsing.
var2 is simply a bunch of char-pointers, it can point to whatever char is necessary, it doesn't necessarily have to be at the beginning of the string.
The calls to free() are somewhat OK (except for the bug - see below). It's normal for the content of free()d blocks to be overwritten when they are returned to the stack, so they often seem to have "rubbish" characters in them if printed out afterwards.
There is some issues with the assignment of var1 ~
var1 = "01234567";
Here you are saying "var1 now points to this constant string". Your compiler may have generated a warning about about this. Firstly the code assigns a const char* to a char* (hard-coded strings are const, but C compilers will only warn about this [EDIT: this is true for C++, not C, see comment from n.m.]). And secondly, the code lost all references to the block of memory that var1 used to point to. You can now never free() this memory - it has leaked. However, at the end of the program, the free() is trying to operate on a pointer-to a block of memory (the "01234567") which was not allocated on the heap. This is BAD. Since you're exiting immediately, there's no ill-effects, but if this was in the middle of execution, the next allocation (or next 1000th!) could crash weirdly. These sorts of problems are hard to debug.
Probably what you should have done here (I'm guessing your intention though) is used a string copy:
strncpy(var1, "01234567", 8);
With that operation instead of the assignment, everything is OK. This is because the digits are stored in the memory allocated on line1.
Question 4 - what's wrong
You 'calloc' some memory and store a pointer to it in var1. Then later you execute var1 = "01234567" which stores a pointer to a literal string in var1, thus losing the calloc'd memory. I imagine you thought you were copying a string. Use strcpy or similar.
Then you write zero values into what var1 points to. Since that's a literal string, it may fail if the literal is in read-only memory. The result is undefined.
free(var1) is not going to go well with a pointer to a literal. Your code may fail or you may get heap corruption.
Pointers don't work this way.
If someone wrote
int a = 6*9;
a = 42;
you would wonder why they ever bothered to initialise a to 6*9 in the first place — and you would be right. There's no reason to. The value returned by * is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to
int a = 42;
Now when pointers are involved, there's some kind of evil neural pathway in our brain that tries to tell us that a sequence of statements that is exactly like the one shown above is somehow working differently. Don't trust your brain. It isn't.
char *var1 = calloc(8,sizeof(char));
var1 = "01234567";
You would wonder why they ever bothered to initialise var1 to calloc(8,sizeof(char)); in the first place — and you would be right. There's no reason to. The value returned by calloc is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to
char* var1 = "01234567";
... which is a problem, because you cannot modify string literals.
What you probably want is
char *var1 = calloc(8, 1); // note sizeof(char)==1, always
strncpy (var1, "01234567", 8); // note not strcpy — you would need 9 bytes for it
or some variation of that.
var1 = "01234567"; is not correct because you assign a value of pointer to const char to a pointer to mutable char and causes a memory leak because the value of pointer to a calloc allocated buffer of 8 char stored in variable var1 is lost. It seems like you actually intended to initialize allocated array with the value of the string literal instead (though that would require allocation of an array of 9 items). Assignment var1[2] = '\0'; causes undefined behavior because the location var1 points to is not mutable. var2[0] = var1[0]; is wrong as well because you assign a value of char to pointer to char. Finally free(var1); will try to deallocate a pointer to buffer baking string literal, not something you allocated.
Program was programmed in C and compiled with GCC.
I was trying to help a friend who was trying to use trying to (shallow) copy a value that was passed into a function. His the value was a struct that held primitives and pointers (no arrays or buffers). Unsure of how malloc works, he used it similar to how the following was done:
void some_function(int rand_params, SOME_STRUCT_TYPEDEF *ptr){
SOME_STRUCT_TYPEDEF *cpy;
cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));// this line makes a difference?!?!?
cpy = ptr;// overwrites cpy anyway, right?
//prints a value in the struct documented to be a char*,
//sorry couldn't find the documentation right now
}
I told him that the malloc shouldn't affect the program, so told him to comment it out. To my surprise, the malloc caused a different output (with some intended strings) from the implementation with the malloc commented out (prints our garbage values). The pointer that's passed into the this function is from some other library function which I don't have documentation for at the moment. The best I can assume it that the pointer was for a value that was actually a buffer (that was on the stack). But I still don't see how the malloc can cause such a difference. Could someone explain how that malloc may cause a difference?
I would say that the evident lack of understanding of pointers is responsible for ptr actually pointing to memory that has not been correctly allocated (if at all), and you are experiencing undefined behaviour. The issue is elsewhere in the program, prior to the call to some_function.
As an aside, the correct way to allocate and copy the data is this:
SOME_STRUCT_TYPEDEF *cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));
if (cpy) {
*cpy = *ptr;
// Don't forget to clean up later
free(cpy);
}
However, unless the structure is giant, it's a bit silly to do it on the heap when you can do it on the stack like this:
SOME_STRUCT_TYPEDEF cpy = *ptr;
I can't see why there difference in the print.
can you show the print code?
anyway the malloc causes memory leak. you're not supposed to allocate memory for 'cpy' because pointer assignment is not shallow-copy, you simply make 'cpy' point to same memory 'ptr' point by storing the address of the start of that memory in 'cpy' (cpy is mostly a 32/64 bit value that store address, in case of malloc, it will store the address of the memory section you allocated)
i am just started learning pointers in c. I have following few doubts. If i find the answers for the below questions. It Will be really useful for me to understand the concept of pointers in c. Thanks in advance.
i)
char *cptr;
int value = 2345;
cptr = (char *)value;
whats the use of (char *) and what it mean in the above code snippet.
ii)
char *cptr;
int value = 2345;
cptr = value;
This also compiles without any error .then whats the difference between i & ii code snippet
iii) &value is returning address of the variable. Is it a virtual memory address in RAM? Suppose another c program running in parallel, will that program can have same memory address as &value. Will each process can have duplicate memory address same as in other process and it is independent of each other?
iv)
#define MY_REGISTER (*(volatile unsigned char*)0x1234)
void main()
{
MY_REGISTER=12;
printf("value in the address tamil is %d",(MY_REGISTER));
}
The above snippet compiled successfully. But it outputs segmentation fault error. I don't know what's the mistake I am doing. I want to know how to access the value of random address, using pointers. Is there any way? Will program have the address 0x1234 for real?
v) printf("value at the address %d",*(236632));//consider the address 236632 available in
//stack
why does the above printf statement showing error?
That's a type cast, it tells the compiler to treat one type as some other (possibly unrelated) type. As for the result, see point 2 below.
That makes cptr point to the address 2345.
Modern operating systems isolate the processes. The address of one variable in one process is not valid in another process, even if started with the same program. In fact, the second process may have a completely different memory map due to Address Space Layout Randomisation (ASLR).
It's because you try to write to address 0x1234 which might be a valid address on some systems, but not on most, and almost never on a PC running e.g. Windows or Linux.
i)
(char *) means, that you cast the data stored in value to a pointer ptr, which points to a char. Which means, that ptr points to the memory location 2345. In your code snipet ptr is undefined though. I guess there is more in that program.
ii)
The difference is, that you now write to cptr, which is (as you defined) a pointer pointing to a char. There is not much of a difference as in i) except, that you write to a different variable, and that you use a implicit cast, which gets resolved by the compiler. Again, cptr points now to the location 2345 and expects there to be a char
iii)
Yes you can say it is a virtual address. Also segmentation plays some parts in this game, but at your stage you don't need to worry about it at all. The OS will resolve that for you and makes sure, that you only overwrite variables in the memory space dedicated to your program. So if you run a program twice at the same time, and you print a pointer, it is most likely the same value, but they won't point at the same value in memory.
iv)
Didn't see the write instruction at first. You can't just write anywhere into memory, as you could overwrite another program's value.
v)
Similar issue as above. You cannot just dereference any number you want to, you first need to cast it to a pointer, otherwise neither the compiler, your OS nor your CPU will have a clue, to what exactely it is pointing to
Hope I could help you, but I recommend, that you dive again in some books about pointers in C.
i.) Type cast, you cast the integer to a char
ii.) You point to the address of 2345.
iii.) Refer to answer from Joachim Pileborg. ^ ASLR
iv.) You can't directly write into an address without knowing if there's already something in / if it even exists.
v.) Because you're actually using a pointer to print a normal integer out, which should throw the error C2100: illegal indirection.
You may think pointers like numbers on mailboxes. When you set a value to a pointer, e.g cptr = 2345 is like you move in front of mailbox 2345. That's ok, no actual interaction with the memory, hence no crash. When you state something like *cptr, this refers to the actual "content of the mailbox". Setting a value for *cptr is like trying to put something in the mailbox in front of you (memory location). If you don't know who it belongs to (how the application uses that memory), it's probably a bad idea. You could use "malloc" to initialize a pointer / allocate memory, and "free" to cleanup after you finish the job.
I've just started to learn C so please be kind.
From what I've read so far regarding pointers:
int * test1; //this is a pointer which is basically an address to the process
//memory and usually has the size of 2 bytes (not necessarily, I know)
float test2; //this is an actual value and usually has the size of 4 bytes,
//being of float type
test2 = 3.0; //this assigns 3 to `test2`
Now, what I don't completely understand:
*test1 = 3; //does this assign 3 at the address
//specified by `pointerValue`?
test1 = 3; //this says that the pointer is basically pointing
//at the 3rd byte in process memory,
//which is somehow useless, since anything could be there
&test1; //this I really don't get,
//is it the pointer to the pointer?
//Meaning, the address at which the pointer address is kept?
//Is it of any use?
Similarly:
*test2; //does this has any sense?
&test2; //is this the address at which the 'test2' value is found?
//If so, it's a pointer, which means that you can have pointers pointing
//both to the heap address space and stack address space.
//I ask because I've always been confused by people who speak about
//pointers only in the heap context.
Great question.
Your first block is correct. A pointer is a variable that holds the address of some data. The type of that pointer tells the code how to interpret the contents of the address being held by that pointer.
The construct:
*test1 = 3
Is called the deferencing of a pointer. That means, you can access the address that the pointer points to and read and write to it like a normal variable. Note:
int *test;
/*
* test is a pointer to an int - (int *)
* *test behaves like an int - (int)
*
* So you can thing of (*test) as a pesudo-variable which has the type 'int'
*/
The above is just a mnemonic device that I use.
It is rare that you ever assign a numeric value to a pointer... maybe if you're developing for a specific environment which has some 'well-known' memory addresses, but at your level, I wouldn't worry to much about that.
Using
*test2
would ultimately result in an error. You'd be trying to deference something that is not a pointer, so you're likely to get some kind of system error as who knows where it is pointing.
&test1 and &test2 are, indeed, pointers to test1 and test2.
Pointers to pointers are very useful and a search of pointer to a pointer will lead you to some resources that are way better than I am.
It looks like you've got the first part right.
An incidental thought: there are various conventions about where to put that * sign. I prefer mine nestled with the variable name, as in int *test1 while others prefer int* test1. I'm not sure how common it is to have it floating in the middle.
Another incidental thought: test2 = 3.0 assigns a floating-point 3 to test2. The same end could be achieved with test2=3, in which case the 3 is implicitly converted from an integer to a floating point number. The convention you have chosen is probably safer in terms of clarity, but is not strictly necessary.
Non-incidentals
*test1=3 does assign 3 to the address specified by test.
test1=3 is a line that has meaning, but which I consider meaningless. We do not know what is at memory location 3, if it is safe to touch it, or even if we are allowed to touch it.
That's why it's handy to use something like
int var=3;
int *pointy=&var;
*pointy=4;
//Now var==4.
The command &var returns the memory location of var and stores it in pointy so that we can later access it with *pointy.
But I could also do something like this:
int var[]={1,2,3};
int *pointy=&var;
int *offset=2;
*(pointy+offset)=4;
//Now var[2]==4.
And this is where you might legitimately see something like test1=3: pointers can be added and subtracted just like numbers, so you can store offsets like this.
&test1 is a pointer to a pointer, but that sounds kind of confusing to me. It's really the address in memory where the value of test1 is stored. And test1 just happens to store as its value the address of another variable. Once you start thinking of pointers in this way (address in memory, value stored there), they become easier to work with... or at least I think so.
I don't know if *test2 has "meaning", per se. In principle, it could have a use in that we might imagine that the * command will take the value of test2 to be some location in memory, and it will return the value it finds there. But since you define test2 as a float, it is difficult to predict where in memory we would end up, setting test2=3 will not move us to the third spot of anything (look up the IEEE754 specification to see why). But I would be surprised if a compiler would allow such thing.
Let's look at another quick example:
int var=3;
int pointy1=&var;
int pointy2=&pointy1;
*pointy1=4; //Now var==4
**pointy2=5; //Now var==5
So you see that you can chain pointers together like this, as many in a row as you'd like. This might show up if you had an array of pointers which was filled with the addresses of many structures you'd created from dynamic memory, and those structures contained pointers to dynamically allocated things themselves. When the time comes to use a pointer to a pointer, you'll probably know it. For now, don't worry too much about them.
First let's add some confusion: the word "pointer" can refer to either a variable (or object) with a pointer type, or an expression with the pointer type. In most cases, when people talk about "pointers" they mean pointer variables.
A pointer can (must) point to a thing (An "object" in standards parlance). It can only point to the right kind of thing; a pointer to int is not supposed to point to a float object. A pointer can also be NULL; in that case there is no thing to point to.
A pointertype is also a type, and a pointer object is also an object. So it is allowable to construct a pointer to pointer: the pointer-to-pointer just stores the addres of the pointer object.
What a pointer can not be:
It cannot point to a value: p = &4; is impossible. 4 is a literal value, which is not stored in an object, and thus has no address.
the same goes for expressions: p = &(1+4); is impossible, because the expression "1+4" does not have a location.
the same goes for return value p = &sin(pi); is impossible; the return value is not an object and thus has no address.
variables marked as "register" (almost distinct now) cannot have an address.
you cannot take the address of a bitfield, basically because these can be smaller than character (or have a finer granularity), hence it would be possible that different bitmasks would have the same address.
There are some "exceptions" to the above skeletton (void pointers, casting, pointing one element beyond an array object) but for clarity these should be seen as refinements/amendments, IMHO.
I have this function which is called about 1000 times from main(). When i initialize a pointer in this function using malloc(), seg fault occurs, possibly because i did not free() it before leaving the function. Now, I tried free()ing the pointer before returning to main, but its of no use, eventually a seg fault occurs.
The above scenario being one thing, how do i initialize double pointers (**ptr) and pointer to array of pointers (*ptr[])?
Is there a way to copy a string ( which is a char array) into an array of char pointers.
char arr[]; (Lets say there are fifty such arrays)
char *ptr_arr[50]; Now i want point each such char arr[] in *ptr_arr[]
How do i initialize char *ptr_arr[] here?
What are the effects of uninitialized pointers in C?
Does strcpy() append the '\0' on its own or do we have to do it manually? How safe is strcpy() compared to strncpy()? Like wise with strcat() and strncat().
Thanks.
Segfault can be caused by many things. Do you check the pointer after the malloc (if it's NULL)? Step through the lines of the code to see exactly where does it happen (and ask a seperate question with more details and code)
You don't seem to understand the relation of pointers and arrays in C. First, a pointer to array of pointers is defined like type*** or type**[]. In practice, only twice-indirected pointers are useful. Still, you can have something like this, just dereference the pointer enough times and do the actual memory allocation.
This is messy. Should be a separate question.
They most likely crash your program, BUT this is undefined, so you can't be sure. They might have the address of an already used memory "slot", so there might be a bug you don't even notice.
From your question, my advice would be to google "pointers in C" and read some tutorials to get an understanding of what pointers are and how to use them - there's a lot that would need to be repeated in an SO answer to get you up to speed.
The top two hits are here and here.
It's hard to answer your first question without seeing some code -- Segmentation Faults are tricky to track down and seeing the code would be more straightforward.
Double pointers are not more special than single pointers as the concepts behind them are the same. For example...
char * c = malloc(4);
char **c = &c;
I'm not quite sure what c) is asking, but to answer your last question, uninitialized pointers have undefined action in C, ie. you shouldn't rely on any specific result happening.
EDIT: You seem to have added a question since I replied...
strcpy(..) will indeed copy the null terminator of the source string to the destination string.
for part 'a', maybe this helps:
void myfunction(void) {
int * p = (int *) malloc (sizeof(int));
free(p);
}
int main () {
int i;
for (i = 0; i < 1000; i++)
myfunction();
return 0;
}
Here's a nice introduction to pointers from Stanford.
A pointer is a special type of variable which holds the address or location of another variable. Pointers point to these locations by keeping a record of the spot at which they were stored. Pointers to variables are found by recording the address at which a variable is stored. It is always possible to find the address of a piece of storage in C using the special & operator. For instance: if location were a float type variable, it would be easy to find a pointer to it called location_ptr
float location;
float *location_ptr,*address;
location_ptr = &(location);
or
address = &(location);
The declarations of pointers look a little strange at first. The star * symbol which stands in front of the variable name is C's way of declaring that variable to be a pointer. The four lines above make two identical pointers to a floating point variable called location, one of them is called location_ptr and the other is called address. The point is that a pointer is just a place to keep a record of the address of a variable, so they are really the same thing.
A pointer is a bundle of information that has two parts. One part is the address of the beginning of the segment of memory that holds whatever is pointed to. The other part is the type of value that the pointer points to the beginning of. This tells the computer how much of the memory after the beginning to read and how to interpret it. Thus, if the pointer is of a type int, the segment of memory returned will be four bytes long (32 bits) and be interpreted as an integer. In the case of a function, the type is the type of value that the function will return, although the address is the address of the beginning of the function executable.
Also get more tutorial on C/C++ Programming on http://www.jnucode.blogspot.com
You've added an additional question about strcpy/strncpy.
strcpy is actually safer.
It copies a nul terminated string, and it adds the nul terminator to the copy. i.e. you get an exact duplicate of the original string.
strncpy on the other hand has two distinct behaviours:
if the source string is fewer than 'n' characters long, it acts just as strcpy, nul terminating the copy
if the source string is greater than or equal to 'n' characters long, then it simply stops copying when it gets to 'n', and leaves the string unterminated. It is therefore necessary to always nul-terminate the resulting string to be sure it's still valid:
char dest[123];
strncpy(dest, source, 123);
dest[122] = '\0';