ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Distribution: Ubuntu Server, Slackware, Red Hat 6.1
Posts: 241
Rep:
a question about array pointers in C
Lately I've been following a tutorial on the C program language. Most of its been a breeze but I'm stuck on this one part about pointers dealing with arrays. Here's the code:
Code:
int add_array(int array[], int size)
{
int i;
int total = 0;
for(i = 0; i < size; i++)
total += array[i];
return(total);
}
I understand the everything except the function declaration, int add_array(int array[], int size). I just don't understand the point of "int array[]" other than it has something to do with a pointer. When I create a main function and call "add_array(10,10)" I get a warning saying "passing arg 1 of 'add_array' makes pointer from integer without cast". (and a segment fault when the program is executed)What is a cast and what exactly are you supposed to put in the first argument slot?
Hi veritas,
Your function wants to receive an array pointer as the first argument and you are giving it an integer. In the main function you have to declare an array
Code:
int xyz[10];
then initialize it and then pass it to the function.
Code:
add_array(xyz, 10);
The compile warning told you you are passing an integer "10" in place of an array pointer. So the function tried to use the number 10 as the memory address of your array. As it was out of bounds, you got the seg fault in the execution.
Remember, c will always try to follow your desires or die trying to do it. I always look for every warning and I remove it because, in a "warning forest" we cannot discover the bad ones.
a cast is a way to tell the compiler to interpret something as a different type than it would normally interpret, and to tell it you know exactly what you are doing.
in your case, 10 is normally an integer. that's why the compiler complains when you give add_array an integer when add_array expects an integer pointer. now, if you want to get rid of the warning, you can do add_array((integer *)10, 10), which tells the compiler that you know exactly that the address 10 points to an integer. of course, you will still get the seg fault run time error because the address 10 doesn't belong to you.
If somehow you knew that 10 was a valid pointer, you'd be able to cast 10 to a pointer to avoid the warning. However, you'd still get the segfault because you'll never see 10 be a valid pointer. To get rid of the warning you'd do add_array((int *)10, 10);
Distribution: Ubuntu Server, Slackware, Red Hat 6.1
Posts: 241
Original Poster
Rep:
Quote:
Originally posted by osvaldomarques
Code:
int xyz[10];
Ah ok. That helps a lot, mainly because I didn't know I was supposed to declare that in the main function. The tutorial just gave me the add_array function without the main function. Thanks for all of the replys. Now this is making sense.
is basiaclly the same thing. However, it is faster. You see, when the function add_array gets called, the variables array and size are created (on the stack?) and the values that belong to them are assigned to them. So when you have an array, say of 100, then 100 values have to get assigned at each function call! (actually +1 for size). But using pointers, you only ever need one value assigned (+1 for size) because a pointer only holds the value of the start of an array, or the address of an array.
So you have a memory chunk in your computer, like so:
1...2...10 n
---------------------------------------
And when you typecast 10 to a address your function will start assigning values from memory startying at 10. Just put it this way, you'll NEVER see a memory address of 10! So basically, your program is trying to access and/or give itself memory, or maybe something else, that doesn't belong to it. Here is the difference between a intager variable, and an intager array (V is where the value is in memory):
Int Var: (memory) V-----------------
Int Array: (memory) VVVVVVVVVV----
So this would be perfectly valid:
int var=1;
add_array((int *)&var, 1);
However, if you said:
add_array((int *)&var, 2);
You would cause a SEGV because you are trying to access memory beyond the address location where var is stored in memory.
Sum:
int add_array(int array[], int size)
this is the same as the following except that it is way slower and take way more memory:
int add_array(int *array, int size)
Sorry I don't write to well, I hope you understand and get the picture.
Hi veritas,
When there is doubt, the computer always have reason. So, I wrote a little piece of c to check the assembler code produced. Intentionally I left one of the warnings which make the "forest" and its easy to remove. The c source file has 3 identical functions, one with pointer declaration, one with an empty array and one with a full array declaration. All the 3 functions are called from main. I compiled it to generate assembler source instead of generate final code. Here is the test.c source
Code:
int add_full_array(int arr[10], int size)
{
int ret
;
ret = *arr * size;
return(ret);
}
int add_array(int arr[], int size)
{
int ret
;
ret = *arr * size;
return(ret);
}
int add_pointer(int *ptr, int size)
{
int ret
;
ret = *ptr * size;
return(ret);
}
void main(void)
{
int tst[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
;
int var
;
var = 1;
add_full_array(tst, 10);
var = 2;
add_array(tst, 10);
var = 3;
add_pointer(tst, 10);
var = 4;
}
In the c, on the main function, I introduced a variable called "var", and before each function call I initialized it to ease the tracking of the start and end of the function calls into the resulting assembler. In the resulting assembler, I did some notes after '#' in the main function, showing the array initialization and marking where the var variable is initialized. As we can see, the code of the 3 functions are completely identical and the assembler instructions to call each of the functions are also the same.
That's the part of my life I most hate. When I disagree with the computer, it is always right! By the way, the command used to compile it is
phew, The_Nerd scared the hell out of me because I haven't used C in a while and what The_Nerd said was completely different than what I remembered. I thought my C was so rusty. but thanks to osvaldomarques, i didn't have to verify the situation.
edit: I will continue with the other one when i get a complete grasp on pointers dealing with the most common data types. I wonder why the strath.ac.uk website went into pointers so early (since they deal with memory locations and other non newbie friendly things)? There is probably another way to demonstrate a while loop.
is basiaclly the same thing. However, it is faster. You see, when the function add_array gets called, the variables array and size are created (on the stack?) and the values that belong to them are assigned to them. So when you have an array, say of 100, then 100 values have to get assigned at each function call! (actually +1 for size). But using pointers, you only ever need one value assigned (+1 for size) because a pointer only holds the value of the start of an array, or the address of an array.
No, array arguments to functions are passed as pointers; they aren't copied. If you use int array[] instead of int *array as the argument, the only difference is that you could modify the 'array' variable. In general:
int *foo;
and
int foo[];
are exactly the same except for the fact that in the first one, 'foo' is a variable and can have its value changed, whereas in the second, 'foo' is not a variable and its value is fixed.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.