Passing and returning arrays in C [duplicate] - c

This question already has answers here:
Returning an array using C
(8 answers)
Closed 8 years ago.
Following are two code snippets. One worked correctly but the other failed.
Main Function
int main
{
int *x,*y,n,*c;
//some code
c=myfunc(x,y,n);
//rest code
}
Here is the code that worked:
int * myfunc(int *a, int *b, int n)
{
int *s,i,*t;
for(i=0;i<n;i++)
s[i]=x[i]+y[i];
t=s;
return s;
}
And here is the code that doesn't work
int * myfunc(int *a, int *b, int n)
{
int s[100],i,*t;
for(i=0;i<n;i++)
s[i]=x[i]+y[i];
t=&s[0];
return t;
}
What happens here is that even though the returned value is the correct address(tested and checked) the contents seemed to get modified on its own. However this did not seem to be the case in the first scenario.
Not only that but the entire array of s[100] has different contents at the end of the executed query. Which basically means the contents of all these addresses are getting modified because of some random reason.
The compiler used was Turbo C.
EDIT
Question in Straight forward terms:
Why does the contents of s when initialized as s[100] get reset after returning and where as contents of s when initialized as *s does not reset. Please note: I Have Not used malloc() or functions that has anything to do with stacks anywhere on my code.

Nothing random about it. You're returning the address of a local variable, which ceases to exist once the function returns. That space is freed up for future function calls, variables, etc.
int * myfunc(int *a, int *b, int n)
{
int s[100],i,*t;
//some operation
t=&s[0];
return t;
} // <!-- s is no longer valid after this point, so t is pointing nowhere

In the code that doesn't work, s[100] is an array on the stack, and goes out of scope when the function returns. In the working code, you don't show how s is allocated, but presumably it's with a malloc, or some other non-stack allocation.
In general, you should not return pointers to stack variables because the stack variables will get overwritten as soon as the function returns.
PS. get a real compiler already :)

Related

Passing Pointers to Functions in C [duplicate]

This question already has an answer here:
Confusion about the fact that uninitialized pointer points to anywhere
(1 answer)
Closed 4 years ago.
I'm going to take data structures course this year, so I decided to renew my knowledge about C by doing some simple tasks about pointers in C, and I have noticed one thing about passing pointers to functions, that I can't really understand.
Let's say we have a function:
void assignValueTen(int *var){
*var=10;
}
We can call this function from main like this:
int main( void ){
int x;
assignValueTen(&x);
printf("The value of x is %d.\n",x);
return 0;
}
The output of this would be:
The value of x is 10.
We can also call this function like this:
int main( void ){
int x, *y;
y=&x;
assignValueTen(y);
printf("The value of x is %d.\n",x);
return 0;
}
The output of this would also be:
The value of x is 10.
However, the statement below does not work as expected:
int main( void ){
int *x;
assignValueTen(x);
printf("The value of x is %d.\n",*x);
return 0;
}
Output of the code above is:
Process exited after 6.723 seconds with return value 3221225477
So, why does the code compile but not work as expected?
Is it because the pointer is not yet assigned to any address before in the last example?
Can somebody explain why this is happening in a little more detail?
Thanks a lot!
The one that does not work is because x is not assigned any value in particular. The assignment in the function is assigning wherever that uninitialized variable happens to point and that is very unlikely to be a valid address (as the hardware sees things) and even if it is valid (again according to the hardware) it is not somewhere you should be writing to (because the address would 'belong' to something other than the code you are running in main).
You should only access addresses you have reason to know are valid (your assignValueTen function has such as an implicit requirement), C does not really have a way to enforce such requirement contracts though some other languages do.
Because when you do:
int main( void ){
int x;
assignValueTen(&x);
printf("The value of x is %d.\n",x);
return 0;
}
or:
int main( void ){
int x, *y;
y=&x;
assignValueTen(y);
printf("The value of x is %d.\n",x);
return 0;
}
you're always printing an int , while in the last example you're trying to print a pointer to an int, or at least that's the way i see it.

Use of automatic variable outside its scope in C [duplicate]

This question already has answers here:
What happens when a variable goes out of scope?
(3 answers)
Closed 6 years ago.
I am studying the working of an automatic variable. I know that it is only accessible inside the block or function in which it is declared and its lifetime is within that same function or block. So the following piece of code I am trying to check.
/Declaration of header files/
void testfn(void);
int *p;
int main(void)
{
testfn();
print("%d\n",*p);
return 0;
}
void testfn(void)
{
int x=444;
p=&x;
}
The output is - 444
I am wondering that when the testfn(); exits,the variable x will be destroyed. Then how in main function the pointer (*p) prints 444.
How this works...or if I am missing something.
Please clarify my doubt.
Thanks
It is coincidence that the original value still remains. With another compiler, or with another compilation configuration, it could take any other value or the program could just crash.
If between the testfn and printf functions you call any other function that does something with its local variables, you might see that the 444 value is not obtained anymore. But this is just, again, coincidence.
p points to the stack where x was stored. If the memory location hasn't been used for something else you will most likely get 444.
Try to insert another function call before printing p and see what happens:
#include <stdio.h>
#include <math.h>
void foo() {
int y=123;
}
void testfn(void);
int *p;
int main(void)
{
testfn();
foo();
printf("%d\n",*p);
return 0;
}
void testfn(void)
{
int x=444;
p=&x;
}
On my machine, the output is now:
123
Since the code results in undefined behaviour, the result could be different if I try this on another platform. But you can see that undefined behaviour can lead to strange bugs.
The memory location that was previously reserved for variable x is not overwritten yet. But it may be at any time. That's why your code leads to undefined behaviour.
In the following example, the memory location that was previously reserved for variable x will be overwritten by the value that is assigned to the variable y. Since the pointer p still points to that location, *p will evaluate to this new value:
#include <stdio.h>
int *p;
void test1(void) {
int x = 444;
p = &x;
}
void test2() {
int y = 15;
}
int main(void) {
test1();
test2();
printf("%d\n",*p);
return 0;
}
The fact that the value still remains is completly coincidental (not guaranteed) because nothing has overwritten it yet.
You can not count on this, it may fail, may print garbage or may crash your program or pc even.
Don't use this, it is considered undefined behavior.

Returning a tuple from a function in C

I need some hint for implementing this algorithm in C. This is a maximum subarray problem. I have made the polynomial time program and also linear time program. I am new to C so I don't know how to return multiple values from a function as this algorithm requires it. For example this line in the algorithm (left-low,left-high,left-sum)=FIND-MAXIMUM-SUBARRAY(A,low,mid) where FIND-MAX-SUBARRAY(A,low,mid) is a recursive function call.
This is the algorithm from coremen:
Below I have set the global variables cross-low,cross-high,cross-sum . How can I do the same for left-low,left-high,left-sum and right-low,right-high,right-sum?
#include "max_subarray_common.h"
#define SENTINAL -3000
int left_low,left_high,left_sum;
int right_low,right_high,right_sum;
int cross_low,cross_high,cross_sum;
void max_crossing_subarray(int low,int mid,int high)
{
int left_sum=SENTINAL;
int sum=0;
int max_left=low,max_right=high;
for(int i=mid;i>=low;i--)
{
sum=sum+change[i];
if(sum>left_sum)
{
left_sum=sum;
max_left=i;
}
}
int right_sum=0;
sum=0;
for(int j=mid+1;j<=high;j++)
{
sum=sum+change[j];
if(sum>right_sum)
{
right_sum=sum;
max_right=j;
}
}
cross_low=max_left;
cross_high=max_right;
cross_sum=left_sum+right_sum;
}
This is my header file:
#ifndef max_subarray_h
#define max_subarray_h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
extern int price[];
extern int n;
extern int change[];
extern int from;
extern int to;
extern int max;
void init_change();
void max_subarray_poly();
void max_subarray_crossing();
void max_subarray_rec();
void max_crossing_subarray();
#endif
change[] is the array for which the subarray is to be found. Also my output should look like this:
from=8
to=11
maximum profit=43
You can achieve the objective by defining a structure using the keyword 'struct' that will hold the three variables you intend to return. To do this, add structure definition at the Header section of your c program.
typedef struct left {
int left_low;
int left_high;
int left_sum;
}LEFT;
Define a variable of type LEFT in your main (or where you want to use it)
Note. Return type of your FIND-MAXIMUM-SUBARRAY will be LEFT. You also need to pass your variable 'stleft' to your FIND-MAXIMUM-SUBARRAY function.
LEFT stleft;
Allocate memory to stleft
stleft = malloc(sizeof(LEFT));
Assign values to be returned , to your variable "stleft"
stleft.left_low = max_left;
stleft.left_high = max_left;
stleft.left_sum = left_sum + right_sum;
Return your variable
return stleft;
Accessing left_low in stleft
int newvar1;
newvar1 = stleft.left_low;
For more help lookup C structures
The function computes 3 different indicators for the set of arguments, there are multiple ways to return multiple results:
add extra arguments, one for each result, as pointers to int or whatever type is more appropriate. Store the results indirectly into the variables whose addresses have been passed by the caller before returning a completion code.
add an extra argument to the function, pointer to a structure with one member per result, and populate this structure before return a success code to the caller.
return such a structure by value. This approach is less idiomatic in C because it was not part of the original pre-Ansi C specification. This was a long time ago, more than 30 years, but it is still frowned upon by many programmers. Another downside of this approach is that you cannot return a failure indication easily. As can be seen from the OP's own usage of this solution, it can lead to very ineffective coding practices.
allocate a structure for the results and return the pointer to the caller. You may indicate failure by returning NULL, but it is less informative than an error code. The life cycle of this structure is error prone: this pointer may get lost if the return value is not stored, care must be taken to free it at the appropriate time.
Returning such results via global variables is definitely not a good solution, for reasons explained in the other answers. The second option above is the one I would recommend.

pointers for getting elements of an array in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
pointer arithmetic in C for getting a string
I am a newbie in C and I would like to get the elements of an array with a function, I have tried different options, but I still do not get the elements.
My function is:
void getelements(int *a, int cl)
{
int *p;
for (p=&a[0];p<&a[cl];p++)
{
printf("%d\n",*p);
}
}
I know that the solution should work like that, but it only prints the first element and then memory positions. I am calling my function with:
int v={10,12,20,34,45};
getelements(&v,5);
Any help? I need to use arithmetic of pointers.
Thanks
First, Please don't update code to fix bugs while a question is open. It makes most of the current answers meaningless, doesn't grant credit where it is due to the person(s) that solved one or more issues in your prior code, and makes the casual reader looking for a related problem to their own completely confused by both the question and the answers therein. If you want to amend an update do so in addition to the original problem, but if it an entirely different issue, then mark as answered, give credit where it is due, and open a new question with your new code and different problem(s) (ideally, anyway).
As written now, your function is fine. But your real issue is this:
// compile with -Wall -Werror and look at the warning here
int v={10,12,20,34,45}; // <== WRONG
getelements(&v,5); // <== Harmless, but bad form.
This should be like this instead, assuming you want to print all elements in the array:
int v[] = {10,12,20,34,45};
getelements(v, sizeof(v)/sizeof(v[0]));
Note the [] following your array. Without it, the &v was masking what would have been a big-fat warning or error from the compiler that int is being passed as an int *. Furthermore, if you compile your prior code with full warnings treated as errors (-Wall -Werror for gcc) you will get an error like the following on your v declaration line:
main.c:116:15: Excess elements in scalar initializer
In other words, everything past the first element was ignored, and thus your pointer was running off into undefined behavior land. Changing the declaration and invocation to what I have above will address this as well as ensure you don't make that mistake again, since sizeof(v[0]) won't even compile unless v is an array or pointer type. The latter can still cause headaches when you use a pointer rather than an array with such a calculation, but thats something you just have to discipline yourself against doing in C.
try this and let me know if that works.
void getelements(int *a)
{
int *p;
int l=5;
for (p=a;p<a+l;p++)
{
printf("%d\n",*p);
}
}
It's best to pass in the length of the array along with the array itself.
#include <stdlib.h>
#include <stdio.h>
void get_elements(int* values, int length)
{
int i;
for (i = 0; i < length; ++i)
{
printf("%d\n", values[i]);
}
}
int main(int argc, char** argv)
{
int vals[3];
vals[0] = 0;
vals[1] = 1;
vals[2] = 2;
get_elements(vals, 3);
getchar();
return 0;
}
Using the code similar to your original post (before the addition of the array length as a method parameter), you could do the follow (which is a bit convoluted if you ask me).
void get_elements(int* values, int length)
{
int *p;
for (p = &values[0]; p < &values[length]; p++)
{
printf("%d\n", *p);
}
}
Actually you are passing array address in
getelements(&v,5)
in function
getelements()
you are treating it like an array!!!
void getelements(int *a, int cl)
{
int *p;
for (p=a;p<a+cl;p++)
{
printf("%d\n",*p);
}
}
Let me know if you are cleared conceptually!!!
As per my knowledge and seeing your code.you have hardcoded the length of array to 5. I think you can also pass array length as a parameter to function; or you can use this function and see if it gives the desired result
void getelements(int *a)
{
int *p;
int i = 0;
int l=5;
p = a
for (i = 0;i<l;i++)
{
printf("%d\n",*(p + i));
}
}

Trying to understand function pointers in C

I am trying to understand function pointers and am stuggling. I have seen the sorting example in K&R and a few other similar examples. My main problem is with what the computer is actually doing. I created a very simple program to try to see the basics. Please see the following:
#include <stdio.h>
int func0(int*,int*);
int func1(int*,int*);
int main(){
int i = 1;
myfunc(34,23,(int(*)(void*,void*))(i==1?func0:func1));//34 and 23 are arbitrary inputs
}
void myfunc(int x, int y, int(*somefunc)(void *, void *)){
int *xx =&x;
int *yy=&y;
printf("%i",somefunc(xx,yy));
}
int func0(int *x, int *y){
return (*x)*(*y);
}
int func1(int *x, int *y){
return *x+*y;
}
The program either multiplies or adds two numbers depending on some variable (i in the main function - should probably be an argument in the main). fun0 multiplies two ints and func1 adds them.
I know that this example is simple but how is passing a function pointer preferrable to putting a conditional inside the function myfunc?
i.e. in myfunc have the following:
if(i == 1)printf("%i",func0(xx,yy));
else printf("%i",func1(xx,yy));
If I did this the result would be the same but without the use of function pointers.
Your understanding of how function pointers work is just fine. What you're not seeing is how a software system will benefit from using function pointers. They become important when working with components that are not aware of the others.
qsort() is a good example. qsort will let you sort any array and is not actually aware of what makes up the array. So if you have an array of structs, or more likely pointers to structs, you would have to provide a function that could compare the structs.
struct foo {
char * name;
int magnitude;
int something;
};
int cmp_foo(const void *_p1, const void *_p2)
{
p1 = (struct foo*)_p1;
p2 = (struct foo*)_p2;
return p1->magnitude - p2->magnitude;
}
struct foo ** foos;
// init 10 foo structures...
qsort(foos, 10, sizeof(foo *), cmp_foo);
Then the foos array will be sorted based on the magnitude field.
As you can see, this allows you to use qsort for any type -- you only have to provide the comparison function.
Another common usage of function pointers are callbacks, for example in GUI programming. If you want a function to be called when a button is clicked, you would provide a function pointer to the GUI library when setting up the button.
how is passing a function pointer preferrable to putting a conditional inside the function myfunc
Sometimes it is impossible to put a condition there: for example, if you are writing a sorting algorithm, and you do not know what you are sorting ahead of time, you simply cannot put a conditional; function pointer lets you "plug in" a piece of computation into the main algorithm without jumping through hoops.
As far as how the mechanism works, the idea is simple: all your compiled code is located in the program memory, and the CPU executes it starting at a certain address. There are instructions to make CPU jump between addresses, remember the current address and jump, recall the address of a prior jump and go back to it, and so on. When you call a function, one of the things the CPU needs to know is its address in the program memory. The name of the function represents that address. You can supply that address directly, or you can assign it to a pointer for indirect access. This is similar to accessing values through a pointer, except in this case you access the code indirectly, instead of accessing the data.
First of all, you can never typecast a function pointer into a function pointer of a different type. That is undefined behavior in C (C11 6.5.2.2).
A very important advise when dealing with function pointers is to always use typedefs.
So, your code could/should be rewritten as:
typedef int (*func_t)(int*, int*);
int func0(int*,int*);
int func1(int*,int*);
int main(){
int i = 1;
myfunc(34,23, (i==1?func0:func1)); //34 and 23 are arbitrary inputs
}
void myfunc(int x, int y, func_t func){
To answer the question, you want to use function pointers as parameters when you don't know the nature of the function. This is common when writing generic algorithms.
Take the standard C function bsearch() as an example:
void *bsearch (const void *key,
const void *base,
size_t nmemb,
size_t size,
int (*compar)(const void *, const void *));
);
This is a generic binary search algorithm, searching through any form of one-dimensional arrray, containing unknown types of data, such as user-defined types. Here, the "compar" function is comparing two objects of unknown nature for equality, returning a number to indicate this.
"The function shall return an integer less than, equal to, or greater than zero if the key object is considered, respectively, to be less than, to match, or to be greater than the array element."
The function is written by the caller, who knows the nature of the data. In computer science, this is called a "function object" or sometimes "functor". It is commonly encountered in object-oriented design.
An example (pseudo code):
typedef struct // some user-defined type
{
int* ptr;
int x;
int y;
} Something_t;
int compare_Something_t (const void* p1, const void* p2)
{
const Something_t* s1 = (const Something_t*)p1;
const Something_t* s2 = (const Something_t*)p2;
return s1->y - s2->y; // some user-defined comparison relevant to the object
}
...
Something_t search_key = { ... };
Something_t array[] = { ... };
Something_t* result;
result = bsearch(&search_key,
array,
sizeof(array) / sizeof(Something_t), // number of objects
sizeof(Something_t), // size of one object
compare_Something_t // function object
);

Resources