I am working on a project for school and I have managed to figure out a work around by doing something really clunky with my code. I have a structure that holds multiple fields, and I am trying to access the following field (as it is declared in the struct named current_event).
int *number_of_couples;
and later down into the program I call this value so I can dynamically allocate an array based on this *number_of_couples field. Essentially I am trying to use this as a "length" operator as C does not have (good) solution.
Before I was trying to implement the following code:
int *permutable_array;
permutable_array = malloc((current_event->number_of_couples) * sizeof(int)); //Line 91
if(permutable_array == NULL){
panic("permutable_array"); //Ensures that Malloc was successful.
}
which would in turn throw the following error:
Line 91: error: invalid operands to binary * (have 'int *' and 'unsigned int')
I have made a very sloppy work around because at this point I just want to get the program working (hour three of pure programming! rock on!). So I implemented:
int *permutable_array;
int avoid_my_bug = (int) current_event->number_of_couples;
permutable_array = malloc(avoid_my_bug * sizeof(int));
if(permutable_array == NULL){
panic("permutable_array");
}
Which works. Now I somewhat understand the error that it is telling me. I suspect it has something to do with the fact that I stored the value of number_of_couples as a pointer within current_event, which is also a pointer. So really if the value of number_of_couples is 4, the path the program makes to get to that value is:
ptr_to_current_event -> ptr_to_number_of_couples -> 4
I can use my sloppy work-around, but it is obvious that I am doing it to avoid a bug. I would rather learn why the code will not compile. I also tried doing:
permutable_array = malloc((*current_event->number_of_couples) * sizeof(int)); //Line 91
which should have dereferenced the pointer returned by current_event->number_of_couples, however it crashes. Any solutions?
*EDIT*
It is initialized by the following line of code:
fscanf(input_file, "%i", ¤t_event->number_of_couples);
and is referenced at least three times (there is a valid int value stored in it) by the program before reaching my code. Remember, the second bit works, therefore it is definitely initialized.
You shouldn't be storing integer values inside pointers. Pointers are made to point at things, you should rarely need to convert a pointer to an integer type. If you do you should use either the uintptr_t or intptr_t types.
You should either dereference the pointer (assuming it is pointing at a valid int) or change the type of number_of_couples so that it is not a pointer. If you leave it as a pointer, you must ensure it is pointing to a valid int object before trying to dereference it, but based on your usage and context above, it doesn't need to be a pointer.
You must dereference the pointer to int
*(current_event->number_of_couples) * sizeof(int)
Casting the pointer to an int, will give you the address of number_of_couples as an integer. This might be some arbitrary large number like 0xf97e1892, for example.
The crash could be a result of number_of_couples not being initialized. You must allocate memory for this pointer. If it is not initialized, it will point to an arbitrary location.
If you initialize it with an integer number_of_couples = 5, it will point to invalid memory. The pointer is only valid, if you allocate memory from the heap or point to another integer variable.
All in all, it seems in your case it is best to define number_of_couples as an int and avoid all the potential pitfalls.
int number_of_couples;
Then, you can just allocate the memory as in your first example.
You should use *(current_event->number_of_couples), that way you will get the value to which pointer is pointing. If you do not use * you will get an address of pointer which you can cast to int but that is not what you want.
Try putting parentheses in your code around current_event->number_of_couples and then use *. If it doesnt help then something else is causing crashing.
If your code is crashing when you dereference this pointer, the chances are that it is pointing to invalid or uninitialised memory. You don't indicate in your question where this gets initialised, but dereferencing an uninitialised pointer is asking for trouble - look into where it gets initialised and if it is pointing to dynamic memory or not.
Related
Say I have a random struct, for example, a chess position.
typedef char chessPos[2];
and I have linked list of chess positions.
typedef struct _chessPosCell
{
chessPos position;
struct _chessPosCell* next;
} chessPosCell;
Now, I want to create a new pointer to a list. so I use the following:
chessPosCell* answer = (chessPosCell*)malloc(sizeof(chessPosCell));
Now, I want to check if the memory has been allocated correctly.
So I want to create a specific function to check EVERY allocation in my code.
void checkAllocation(void* ptr)
{
if (ptr == NULL)
{
printf("Memory allocation failure. \n");
exit(1);
}
}
My question is, how do I send my new allocated memory?
1.
checkAllocation(&answer);
checkAllocation(answer);
(The difference is just the '&')
I'm asking this because I've been discussing with a friend. I'm using option 1, because option 2 gives me Visual Studio warning of "Derefencing NULL pointer "answer".
And the friend says I need to use option 2, because I want to check "answer" allocation, and not it's address allocation. However, option 2 gives me the warning mentioned above!
So I've been a bit confused. Can anyone please explain this part to me?
Thanks in advance!
If you use Visual Studio and write in C language (not C++ which is default) change in project properties language used:
Then you will not need (and you should not) to cast pointers.
(The difference is just the '&')
The & gives the reference (address) of the object.
int *pointer = malloc(sizeof(*pointer));
Defines the variable pointer having type pointer to int and initializes it with the value returned by the function malloc.
If you want to hack if the stored value is NULL you want to use this variable
if(pointer == NULL)
When you add the & you get the reference (address) of the variable pointer not the value stored in this variable.
Same is with other types.
int i = 5;
if(i == 5)
&i will give the reference of the variable i not the value stored in this variable.
Use checkAllocation(answer);.
The definition chessPosCell* answer = (chessPosCell*)malloc(sizeof(chessPosCell)); calls malloc to reserve some memory. malloc returns the address of that memory (or a null pointer). The definition initializes the value of answer to have that address.
checkAllocation(&answer); would pass the address of the object named answer to checkAllocation. chessAllocation(answer) passes the value of the object named answer to checkAllocation. It is the value of answer that is the address return by malloc, and that is what you want to check.
Incidentally, the definition is better written as chessPosCell *answer = malloc(sizeof *answer));:
By using sizeof *answer instead of sizeof(chessPosCell), you get the size of the type being pointed to. This will remain correct even if the type of answer is later changed in code edits.
C automatically converts from void * to other pointer-to-object types, so the cast to (chessPosCell*) is unnecessary. And sometimes using a cast can suppress a warning message about a bug, because compilers assume that casts are intentional, that they indicate the author knows what they are doing.
As I understand it, all of the cases where C has to handle an address involve the use of a pointer. For example, the & operand creates a pointer to the program, instead of just giving the bare address as data (i.e it never gives the address without using a pointer first):
scanf("%d", &foo)
Or when using the & operand
int i; //a variable
int *p; //a variable that store adress
p = &i; //The & operator returns a pointer to its operand, and equals p to that pointer.
My question is: Is there a reason why C programs always have to use a pointer to manage addresses? Is there a case where C can handle a bare address (the numerical value of the address) on its own or with another method? Or is that completely impossible? (Being because of system architecture, memory allocation changing during and in each runtime, etc). And finally, would that be useful being that addresses change because of memory management? If that was the case, it would be a reason why pointers are always needed.
I'm trying to figure out if the use pointers is a must in C standardized languages. Not because I want to use something else, but because I want to know for sure that the only way to use addresses is with pointers, and just forget about everything else.
Edit: Since part of the question was answered in the comments of Eric Postpischil, Michał Marszałek, user3386109, Mike Holt and Gecko; I'll group those bits here: Yes, using bare adresses bear little to no use because of different factors (Pointers allow a number of operations, adresses may change each time the program is run, etc). As Michał Marszałek pointed out (No pun intended) scanf() uses a pointer because C can only work with copies, so a pointer is needed to change the variable used. i.e
int foo;
scanf("%d", foo) //Does nothing, since value can't be changed
scanf("%d", &foo) //Now foo can be changed, since we use it's address.
Finally, as Gecko mentioned, pointers are there to represent indirection, so that the compiler can make the difference between data and address.
John Bode covers most of those topics in it's answer, so I'll mark that one.
A pointer is an address (or, more properly, it’s an abstraction of an address). Pointers are how we deal with address values in C.
Outside of a few domains, a “bare address” value simply isn’t useful on its own. We’re less interested in the address than the object at that address. C requires us to use pointers in two situations:
When we want a function to write to a parameter
When we need to track dynamically allocated memory
In these cases, we don’t really care what the address value actually is; we just need it to access the object we’re interested in.
Yes, in the embedded world specific address values are meaningful. But you still use pointers to access those locations. Like I said above, a pointer is an address for our purposes.
C allows you to convert pointers to integers. The <stdint.h> header provides a uintptr_t type with the property that any pointer to void can be converted to uintptr_t and back, and the result will compare equal to the original pointer.
Per C 2018 6.3.2.3 6, the result of converting a pointer to an integer is implementation-defined. Non-normative note 69 says “The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment.”
Thus, on a machine where addresses are a simple numbering scheme, converting a pointer to a uintptr_t ought to give you the natural machine address, even though the standard does not require it. There are, however, environments where addresses are more complicated, and the result of converting a pointer to an integer may not be straightforward.
int i; //a variable
int *p; //a variable that store adres
i = 10; //now i is set to 10
p = &i; //now p is set to i address
*p = 20; //we set to 20 the given address
int tab[10]; // a table
p = tab; //set address
p++; //operate on address and move it to next element tab[1]
We can operate on address by pointers move forward or backwards. We can set and read from given address.
In C if we want get return values from functions we must use pointers. Or use return value from functions, but that way we can only get one value.
In C we don't have references therefore we must use pointers.
void fun(int j){
j = 10;
}
void fun2(int *j){
*j = 10;
}
int i;
i = 5; // now I is set to 5
fun(i);
//printf i will print 5
fun2(&i);
//printf I will print 10
I have the following code that totally works 100% fine, no errors, compile or runtime. But it's damn ugly because I have to cast and use an extraneous variable when I'm sure there's a way to do without either.
structMSGB ***init_bstack(int Blk_Size,int Blks_N)
{
structMSGB **Mp=calloc(Blk_Size,Blks_N);
void *M=(void*)Mp+sizeof(structMSGB*)+sizeof(structMSGB*)*Blks_N;
structMSGB ***startStack=(structMSGB***)Mp++;
for(int i=0;i<Blks_N;i++)
{
*Mp=M+(Blk_Size-sizeof(structMSGB*))*i-(i==1)*sizeof(structMSGB*);
(*Mp)->blk_size=Blk_Size-sizeof(structMSGB)-sizeof(structMSGB*)-(i==0)*sizeof(structMSGB*);
Mp++;
}
*startStack=(structMSGB **)Mp;
return startStack;
}
Specifically, it's the startStack variable that is pissing me off. I feel there should be a way of doing without it altogether. The return value is the address of a ptr to a ptr to a struct, i.e. It needs to return a ptr to a ptr to a ptr to a struct.
The result returned is the starting address of a memory block that is Blk_Size bytes in size and is composed of the following in order:
**ptr variable
table of ptrs of Blk_N length
sequential blocks of size Blk_Size - sizeof(ptr) except for the first block which is sizeof(ptr) smaller.
It's done this way to ensure that the entire memory allocation is used, no more and no less.
Your code invokes undefined behavior when it performs arithmetic on an expression of type void *. Some compilers will treat that as if void * were char *, and if your code in fact works then that's what's happening, but it's still wrong. And probably unnecessary, to boot.
Allow me to introduce you to pointer arithmetic. Given a pointer p of type some_type * and an integer value x, the expression p + x is equivalent to (some_type *) (((char *) p) + (x * sizeof(some_type)). By no coincidence whatever, that's also equivalent to &p[x]. That is, pointer arithmetic is defined in terms of the size of the pointed-to object.
The code you present performs a lot of casting and arithmetic with explicit object sizes that could be eliminated by relying on ordinary pointer arithmetic. For example, this ...
void *M = (void*) Mp + sizeof(structMSGB*) + sizeof(structMSGB*) * Blks_N;
... would be better written
structMSGB **M = Mp + 1 + Blks_N;
Similar applies elsewhere in your code.
More generally, good code rarely requires sizeof other than for memory allocation, and requires very few casts. Any time you find yourself writing a cast, you should ask yourself why, and be sure you have a good answer.
Update:
As for getting rid of variable startStack, it looks like you could do so at the cost of some additional arithmetic. You initialize it to the original value of variable Mp. You then increment Mp at total of Blks_N + 1 times. At the only points where you use startStack, then, its value is equal to Mp - (Blks_N + 1). You could use that expression instead of a variable. I certainly would not make such a change, though.
This is the greatly improved version that solves my problem (with help from #John Bollinger):
void *init_bstack(int Blk_Size,int Blks_N)
{
structMSGB **Mp=calloc(Blk_Size,Blks_N);
Mp[0]=Mp[1]=(void*)&Mp[Blks_N+1];
Mp[1]->blk_size=Blk_Size-sizeof(structMSGB)-sizeof(structMSGB*)sizeof(structMSGB*);
for(int i=1;i<Blks_N;i++)
{
Mp[i+1]=Blk_Size+(void*)Mp[i]-8-(i==1)*8;
Mp[i+1]->blk_size=Blk_Size-sizeof(structMSGB)-sizeof(structMSGB*);
}
return Mp;
}
I use the return value thusly:
structMSGB ***MBp=init_bstack(4096,10);
I can then use *MBp to allocate chunks of memory using:
structMSGB *xb=*(--*Mp);
And when I'm done I can return the chunk with:
*((*Mp)++)=xb;
MBp also contains a value I can later use to free the memory - free(MBp)
I think MBp needs to be a *** type as it contains the address of the calloc'd block, the first 8 bytes of which contains a ptr into a table of ptrs. This address is passed to allocate and free functions, so that the ptr at this address can be incremented or decremented accordingly, and also provide the chunk of memory requested.
The question now becomes, can the code be improved further? I'm casting with a void * when I really don't like to cast but in this case, I don't see any alternative. e.g. If I replace *Mp=(void*)(Mp+Blks_N+1); with *Mp=(Mp+Blks_N+1);, it works but gcc throws up a " assignment from incompatible pointer type" warning. Is there a better alternative to using (void*)?
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.
Yesterday while I was coding in C, my friend asked me pointing to a variable is it pointer or a variable ? I stucked up for a while. I didnt find an aswer to it , I just have to go back and search it and tell him.But I was thinking is there any function to differentiate them.
Can we differentiate a variable against a pointer variable
int a;
sizeof(a); // gives 2 bytes
int *b;
sizeof(b); // gives 2 bytes
// if we use sizeof() we get same answer and we cant say which is pointer
// and which is a variable
Is there a way to find out a variable is a normal variable or a pointer? I mean can someone say that it is a pointer or a variable after looking at your variable that you have declared at the beginning and then going down 1000 lines of your code?
After the comment
I wanted to say explicitly it's a 16 bit system architecture.
First, the question "Is it a pointer or a variable" doesn't make much sense. A pointer variable is a variable, just as an integer variable, or an array variable, is a variable.
So the real question is whether something is a pointer or not.
No, there's no function that can tell you whether something is a pointer or not. And if you think about it, in a statically typed language like C, there can't be. Functions take arguments of certain specified types. You can't pass a variable to a function unless the type (pointer or otherwise) is correct in the first place.
You mean differentiate them at run time without seeing the code? No, you can't. Pointers are variables that hold memory address. You can't check it at run time. That means, there is no such function isPointer(n) that will return true/false based on parameter n.
You can deduce the type from the use.
For example:
char* c;
...
c[0] = 'a';
*c = 'a';
Indexing and dereferencing would let you know it's a pointer to something (or it's an array if defined as char c[SOME_POSITIVE_NUMBER];).
Also, things like memset(c,...), memcpy(c,...) will suggest that c is a pointer (array).
OTOH, you can't normally do with pointers most of arithmetic, so, if you see something like
x = c * 2;
y = 3 / c;
z = c << 1;
w = 1 & c;
then c is not a pointer (array).
Three things:
What platform are you using where sizeof(int) returns 2? Seriously
Pointers are types. A pointer to an int is a type, just like an int is. The sizes of a type and a pointer to that type are sometimes equal but not directly related; for instance, a pointer to a double (on my machine, at least) has size 4 bytes while a double has size 8 bytes. sizeof() would be a very poor test, even if there was a situation where such a test would be appropriate (there isn't).
C is a strictly typed language, and your question doesn't really make sense in that context. As the programmer, you know exactly what a is and you will use it as such.
If you'd like to be able to tell whether a variable is a pointer or not when you see it in the source code, but without going back to look at the declaration, a common approach is to indicate it in the way you name your variables. For example, you might put a 'p' at the beginning of the names of pointers:
int *pValue; /* starts with 'p' for 'pointer' */
int iOther; /* 'i' for 'integer' */
...or even:
int *piSomething; /* 'pi' for 'Pointer to Integer' */
This makes it easy to tell the types when you see the variable in your code. Some people use quite a range of prefixes, to distinguish quite a range of types.
Try looking up "Hungarian notation" for examples.
no , you can't.
and what is the usage, as each time u run the code the pointer address will be different ?? however u can subtract two pointers and also can get the memory address value of any pointer.