Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I have a simple macro:
#define LENGTH(arr) (sizeof(arr)/sizeof(arr[0]))
and for whatever reason, it seems to work fine when setting something like:
int length = LENGTH(arr)
but not to compare with in a loop
while(i < LENGTH(arr))
For the same arr, the macro will either work or it won't.
The likely problem is that the arr in the loop is a pointer rather than an array. The macro does not work with pointers, it only works with arrays.
Remember that arrays decays to pointer when passed around. So if you pass an array to a function, it's not longer an array but a pointer inside the function. A pointer which have only have information about the type, but not the size of the array.
sizeof(arr) is not the same as what a more high level language gives you when you do arr.Count() or arr.Length.
This gives you the storage space of the arr variable. This does not mean the length of the array.
If you have char *arr = malloc(sizeof(*arr) * 100); and you do sizeof(arr) you will usually (depending on your system) get 4. If you do sizeof(*arr) or sizeof(arr[0]), which is the same thing, you have sizeof(char) which is 1, so the macro gives you 4/1 = 4 : wrong. It works with char arr[100] because sizeof(arr) gives you 100 as the array does not decay to a pointer type for sizeof.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have seen allot of posts about the array subscript is above array bounds error and i understand it happends when the iterator equals the max size of the array but my case is different:
static inline void setUninitialized(uint32 * xoBuff, uint32 xiItemSize)
{
uint32 i;
for (i=0 ; i < (xiItemSize/sizeof(uint32)) ; i++)
{
*(xoBuff++) = (uint32)MAP_UNINITIALIZED_VALUE;
}
}
when i run this code i get the array subscript is above array bounds error but i cant figure out why, i have literally tried all the posible combinations of incrementing the iterator and casting all kinds of variables.
the definition of uint32 is:
typedef unsigned long uint32;
any ideas why this keeps happening?
EDIT:
the way that the function is called is as follows:
TableEntry sEntry;
setUninitialized((uint32 *)&sEntry.policyKey, sizeof(PolicyKey));
the policyKey field is of instance PolicyKey
The line
sizeof(PolicyKey)
doesn't give you the size of the array. You can't ever get the size of an array in C. Rather, it's giving you the size of the pointer PolicyKey (assuming that's what it is), which will always be the same size (probably 8). So then (xiItemSize/sizeof(uint32)) will always (again assuming that everything on your computer is normally-sized) evaluate to 2.
It's hard to say anything else without knowing what sEntry looks like, but my guess is that you pass in a buffer that's only one-item long at some point, and it segfaults when it tries to dereference *(xoBuff++).
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
# include <stdio.h>
# include <stdlib.h>
int main(int argc, char *argv[])
{
int a[5][10][2];
int *p;
p = (int(*)[10][2])p;//Gives error!
return EXIT_SUCCESS;
}
I want to type cast p to type so that it can act as a pointer to the given 3-d array?Is there a way to do so.I am applyindg the idea that the type of a variable is everything except variable name.
Why are you trying to "typecast" anything? Why would you expect a value "typecasted" to (int(*)[10][2]) to be compatible with an int * pointer? And why does your original code assigns p to p, completely ignoring a?
This is what you can do
int a[5][10][2];
int (*p)[10][2] = a;
Now p is a pointer that can be used to access a, i.e. p[i][j][k] is equivalent to a[i][j][k]. No typecasting necessary.
If you write p = (int(*)[10][2])a; it won't give you any errors, may be a warning. You are thinking that p will be converted to pointer to a 3-D array, which is wrong. Try this statement after assigning a to p.
printf("addresses %u %u",p,p+1);
According to you, output should be something similar to this(lets say) "addresses 9990000 99940000", because you are thinking p is pointing to 3-D array. However you will get similar to "addresses 9990000 9990004", proving that p is a pointer to an integer.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
#include<stdio.h>
#include<conio.h>
void main()
{
int *(intArray+3);
int i;
int (intArray+3)=&i;
*(intArray+3)=11;
printf("%d%d",i,*(intArray+3));
getch();
in this program i used the concept *(intArray+3)=intArray[3]
with base program
int *p;
int i;
p=&i;
*p=11;
printf("%d%d",i,*p);
in this case o/p is 11,11 but 1st program is based on this concept plez help?
The pointer arithmetic is possible only after defining and initializing a pointer. Now let me explain it:
Suppose there an array intArray of 5 elements ;
int intArray[5];
Let's assume the starting address of intArray is 2000. Now what (intArray + 3) does mean here? It means that (intArray + 3) is now referring to the fourth element (element 3) of the array intArray, i.e, now it is pointing to the location 2012 (as array name can be used as a pointer to its first element), assuming an int type is taking 4 bytes on a machine. When you place a * operator before it then it dereferences the value at that location, i.e, *(intArray + 3) will give you the value stored at the location 2012 which is equivalent to intArray[3].
Since you declared intArray neither as a pointer (for pointer it must be initialized) nor as an array, you can't dereference (intArray + 3). This is invalid and program will not compile.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How can I initialize an array in C such as
void initArr(int size)
{
...
}
The C language does not give the option to initialize an array
if his size is not an constant value, and if I initialize
it generally (int *arr;) so it gives me error of 'arr' is not
being initialized.
Similarily, how can I do that when I have an array with dimension
bigger than one (matrix, for example)?
The answer that works in C and C++ is dynamic memory allocation
int *arr = (int*)malloc(size*sizeof(int));
In C++ you would prefer to use new instead of malloc, but the principle is the same.
int* arr = new int[size];
The C language does not give the option to initialize an array if his size is not an constant value
In C99 you can use a variable length array and then initialize it by using a loop.
if I initialize it generally (int *arr;) so it gives me error of 'arr' is not being initialized.
This is because a pointer must be initialized (points to a pointee - excluding NULL) before it is being used in program.
In C, you can initialize objects to 0 with memset. It's not possible to use memset to portably initialize objects other than character arrays to a repeated non-zero value.
In C++, the same is true, but it is restricted to so-called "POD" objects (Plain Old Data), which are basically the same objects you could have in C (no virtual functions, no private data members, etc. -- the precise definition is in the standard). It's not good C++ style, but it's possible.
In both C and C++ you can find the total size of an array in bytes (which you need to pass to memset) by multiplying the dimensions and the size of a single data element. For example:
void InitializeMatrix(double *m, size_t rows, size_t cols) {
memset(m, 0, rows * cols * sizeof *m);
}
In C99, you can declare a variable length array (VLA), even with multiple dimensions, and if you do so, you can use the sizeof operator directly on the array, which can be a lot more convenient. But there are lots of restrictions on VLAs; they often don't work the way you expect them to. However, the following does work:
double m[rows][cols];
memset(m, 0, sizeof m);
Note that in C99, unlike traditional C or C++, the compiled sizeof operator in this case may actually create run-time code, and therefore violates the expectation of many programmers that sizeof does not evaluate its argument.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 8 years ago.
Improve this question
I have a problem in displaying the size of the array correctly.
I know array size is 256000 but it is displaying as 8 when I enter the loop. size will be displayed accurately if dynamic allocation is not used. How do I rectify the bug using dynamic allocation?
This will give you size 10, because the compiler knows it's an array;
char foo[10];
int size = sizeof foo;
This will give you size 4 on a 32-bit architecture, because it's the size of a pointer.
char *foo = malloc(10 * sizeof(char));
int size = sizeof foo;
After this, the usage of foo is identical. You can do foo[2] or *foo or whatever with both versions. But you probably shouldn't take the address of &foo with the 1st variant. And you should free(foo); sometimes with the 2nd.
Always remember: sizeof is not a function, sizeof is always decided in compile time.