The function func takes void parameter buf. I want to insert values from 1 to 10 into buf by calling func. However, the addresses of buf are different in func and main and the printed values are not from 1 to 10. Can anyone help me with this problem? Thanks!
void func(int n, void *buf);
int main()
{
void *buf;
func(10,buf);
for(int i=0;i<10;i++){
printf("%d\n", ((char*)buf)[i]);
}
printf("in main, after func: %p\n",buf);
}
void func(int n, void *buf)
{
(char*)buf;
char my_array[n];
for(int i=0;i<n;i++){
my_array[i]=i;
}
buf = my_array;
printf("in func: %p\n",buf);
}
You set buf to a pointer that points to memory on the stack (i.e. my_array). Since it is no longer valid as soon as the program leaves func this does not work.
Either use dynamic memory, but then you need to free it explicitly. Another option is to create the memory outside and only fill it inside of func:
#include <stdio.h>
void func(char* buf, int n)
{
for(int i = 0; i < n; i++) {
buf[i]=i;
}
}
int main()
{
char buf[10];
func(buf, sizeof(buf));
for(int i=0; i < sizeof(buf); i++) {
printf("%d\n", buf[i]);
}
}
Apart from that: Never use void* unless you have a VERY good reason for it!
You need to allocate your memory outside of your function, otherwise it will not be valid when you return, because it was allocated on the stack.
void func(int n, int *buf);
int main()
{
const int n = 10;
int my_array[n];
func(n, my_array);
for(int i = 0; i < n; i++){
printf("%d\n", ((int*)my_array)[i]);
}
printf("in main, after func: %p\n", my_array);
}
void func(int n, int *buf)
{
for(int i = 0; i < n; i++){
buf[i] = i;
}
}
Related
I have generated a random array inside the main function, How can I properly print it out using a separate function and inside the function print out the value and memory location of each element of that array using pointers. Here is my code so far:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void printArray(int *pointertoArray, int *Size);
int main (void)
{
srand(time(NULL));
int array[10];
int *pointer = NULL;
for(int i = 0; i < size; i++)
{
array[i] = rand();
*pointer = array[i];
printArray(*pointer,size);
}
}
void printArray(int *pointerToArray, int *size)
{
int i = 0;
do
{
printf("\nValue %d = %p ",i,*pointerToArray);
i++;
}
while(i < size);
}
Here is what I am trying to achieve:
value 1 = 0x7fff0815c0e0
.....
value 10 = 0x7fff0815c0ec
int *size should be int size. You don't pass a pointer, and you don't need a pointer.
Actually, size_t size would be more appropriate.
The call to printArray should be located after the loop. You only want to print the array once.
printArray(*pointer, size); should be printArray(array, size);.
pointerToArray should be named array or pointerToInts.
The value of the element is pointerToArray[i], not i.
The address of the element is pointerToArray+i, not *pointerToArray.
The loop in printArray should be top-tested. (No reason for it to be bottom tested, so play it safe.)
main is declared to return an int, but doesn't.
We get,
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void printArray(int *array, size_t size);
int main() {
srand(time(NULL));
int array[10];
for (int i = 0; i < size; ++i) {
array[i] = rand() % 1000;
}
printArray(array, sizeof(array)/sizeof(array[0]));
return 0;
}
void printArray(int *array, size_t size) {
for (int i = 0; i < size; ++i) {
printf("Value # %p = %d\n", array+i, array[i]);
}
}
Alternative:
void printArray(int *pointerToInt, size_t size) {
for (; size--; ++pointerToInt) {
printf("Value # %p = %d\n", pointerToInt, *pointerToInt);
}
}
I have written the following code in C for initializing and increment an array of pointers to int.
#include <stdio.h>
#include <stdlib.h>
int * arr;
void initArray (int *arr, int size) {
arr = malloc(sizeof(int)*size);
for (int i=0; i< size; i++) {
arr[i]= i;
printf("%d ", arr[i]);
}
printf("\n");
}
void incArray(int *arr, int size) {
for (int i=0; i< size; i++) {
arr[i]= i+1;
printf("%d ", arr[i]);
}
printf("\n");
}
void main(){
initArray(arr, 3);
incArray(arr, 3);
}
Unless I use malloc in both functions, the program (when run) gives this error:
Running "/home/ubuntu/workspace/hello-c-world.c"
0 1 2
bash: line 12: 93714 Segmentation fault "$file.o" $args
Process exited with code: 139
Not sure why once the initArray function is called why it needs memory allocation again in increment function. I am assuming it's treating the array for the second function as a separate one whereas I want to increment the values in the first array that initArray function creates.
I'd really appreciate being pointed in the right direction.
You want this:
#include <stdio.h>
#include <stdlib.h>
void initArray (int **arr, int size) {
*arr = malloc(sizeof(int)*size);
for (int i=0; i< size; i++) {
(*arr)[i]= i;
printf("%d ", (*arr)[i]);
}
printf("\n");
}
void incArray(int *arr, int size) {
for (int i=0; i< size; i++) {
arr[i]= i+1;
printf("%d ", arr[i]);
}
printf("\n");
}
void main(){
int *arr;
initArray(&arr, 3); // << this will modify arr
incArray(arr, 3);
}
In your code, you have two variables whose name is arr : one is inside the global scope, and the other one is in initArray function scope. Look at this instruction inside initArray :
arr = malloc(sizeof(int)*size);
As function's local scope is resolved before global's one in C language, it's the arr parameter of the function which is going to store the allocation, not the global arr variable. And as you're returning nothing, this pointer will be destroyed at the end of your function, and you will not have any access to your allocation anymore. And so, the global arr will never be modified and its value will always be NULL or an undefined value.
This is why, inside incArray when you're doing this writing instruction...
arr[i]= i+1;
... you are actually trying to write i + 1 in a NULL or undefined address, which is not an address your processus has the right to write in, causing this segmentation fault.
A simple fix would be to return the pointer in initArray and to store it in your global arr variable, like that:
int * arr;
int* initArray (int size) {
int* arr = malloc(sizeof(int)*size);
// ...
return arr;
}
void incArray(int *arr, int size) {
// ...
}
void main(){
arr = initArray(3);
incArray(arr, 3);
}
The arr in initArray() is hiding the global arr, and modifications made to arr in initArray() are not made to the global arr. Your code then calls incArray() with the (unmodified) global arr — which is still a null pointer. This gives you a seg fault when you try to use it. It also means that you leak the memory when the function returns.
You'll need to work out whether you want the global variable or not — I suggest removing it. Global variables should be avoided when possible.
You will need to change the signature of the initArray() function — there are (at least) two options.
Option 1 — Return pointer to allocated space
You could change initArray() to return a pointer to the allocated space. It would have the signature int *initArray(int size) and you'd call it as:
int *arr = initArray(3);
This yields:
#include <stdio.h>
#include <stdlib.h>
int *initArray(int size)
{
int *arr = malloc(sizeof(int)*size);
if (arr != 0)
{
for (int i = 0; i < size; i++)
{
arr[i] = i;
printf("%d ", arr[i]);
}
printf("\n");
}
return arr;
}
void incArray(int *arr, int size) // Unchanged
{
for (int i = 0; i < size; i++)
{
arr[i] = i+1;
printf("%d ", arr[i]);
}
printf("\n");
}
int main(void)
{
int *arr = initArray(3);
if (arr != 0)
incArray(arr, 3);
return 0;
}
Where I compare to 0, you may prefer to compare to NULL. Note that the code is careful to check that allocations succeed before using the allocated space.
Option 2 — Pass a pointer to a pointer
Alternatively, if you like double pointers, you can pass a pointer to a pointer to the function:
void initArray(int **arr, int size)
{
*arr = malloc(sizeof(int) * size);
if (*arr != 0)
{
for (int i = 0; i < size; i++)
{
(*arr)[i] = i;
printf("%d ", (*arr)[i]);
}
printf("\n");
}
}
// incArray unchanged again
int main(void)
{
int *arr;
initArray(&arr, 3);
if (arr != 0)
incArray(arr, 3);
return 0;
}
I'm having some issues with very simple situations of passing arrays as pointers into functions and returning them. I thought I had pointers figured but I just can't get my head around it.
Here's the code:
int* getLottoDraw();
void printArray(int * array);
int find_matches(int * array1, int * array2);
int main(int argc, char *argv[])
{
int * lotteryDraw = getLottoDraw();
printArray(lotteryDraw);
system("PAUSE");
return 0;
}
int* getLottoDraw(){
int draw[6];
int i;
srand(time(NULL));
for (i = 0; i < 6; i++) {
int r = rand() % 49;
draw[i] = r;
}
return draw;
}
void printArray(int *array){
int i;
for (i = 0; i < 6; i++){
printf("%i ", array[i]);
}
}
One example output is "3 2047 4614546 0 25 45". Not what was hoping for.
You are returning a stack address, which end up being destroyed when the function ends.
Stack variables are local variables, their scope is limited to the function they're created.
They're created on the function, and destroyed when the function ends, so if you've try to access this address later you'll get undefined behavior.
You should have a dynamic allocated pointer to be able to access it outside the function, or return by value, copying the content (which can be costly in an array case).
You could do something like:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int* getLottoDraw();
void printArray(int * array);
int find_matches(int * array1, int * array2);
int main(int argc, char *argv[])
{
int * lotteryDraw = getLottoDraw();
printArray(lotteryDraw);
free(lotteryDraw);
return 0;
}
int* getLottoDraw(){
int* draw = malloc(sizeof(int)*6);
int i;
srand(time(NULL));
for (i = 0; i < 6; i++) {
int r = rand() % 49;
draw[i] = r;
}
return draw;
}
void printArray(int *array){
int i;
for (i = 0; i < 6; i++){
printf("%i ", array[i]);
}
}
void load(int *n, int *x, int **arr)
{
arr = (int**)malloc(sizeof(int*)*(*n));
for(int i = *n; i >= 0; i--)
{
scanf("%d", &arr[i]);
}
}
int main()
{
int n = 0, x = 0;
int *arr;
load(&n, &x, &arr);
printf("%d", arr[1]);
return EXIT_SUCCESS;
}
The program compiles properly, but it throws windows error during the printf() in main function. Displaying just "arr" gives random big numbers. What is wrong here?
arr = (int**)malloc(sizeof(int*)*(*n));
doesn't change anything in main, it only overwrites the copy of the pointer (address of arr in main) that load receives.
What the function should do is change arr in main, for that, you have to dereference the argument,
*arr = (int*)malloc(sizeof(int)*(*n)); // cast for C++ compiler left in
to change the value of arr in main. (The object that the argument arr of load points to, that is arr in main, needs to be changed, hence you need to modify *arr in load.)
The scans should then be
scanf("%d", &(*arr)[i]);
or (equivalent)
scanf("%d", *arr + i);
#include <stdio.h>
#include <stdlib.h>
void load(int *n, int *x, int **arr)
{
int i = 0;
*arr = (int*) malloc(*n * sizeof(int));
if(!*arr) {
perror("Can not allocate memory!");
return;
}
for(i = *n; i >= 0; i--)
{
scanf("%d", *arr + i);
}
return;
}
int main()
{
int n = 0, x = 0;
int *arr;
int i;
/* You probably need to initialize n */
n = 5;
load(&n, &x, &arr);
for(i = n; i >= 0; i--)
{
printf("%d - %d\n", i, arr[i]);
}
return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
void push(int p)
{
static int i=0;
int b;
int *ptr =(int *)malloc((10)*sizeof(int));
ptr[i]=p;
for(b=0;b<=i;b++){
printf("%d",ptr[b]);
printf("\n");
}
i++;
}
int main()
{
int a;
while(1)
{
scanf("%d",&a);
push(a);
}
}
When i put new values , function is not hold old entries.I wait for your helps.
#include <stdio.h>
#include <stdlib.h>
void push(int p)
{
static int i = 0;
static int ptr[10]; // since you are NOT freeing this memory later,
// there's no need to use malloc.
ptr[i] = p;
int b;
for (b = 0; b <= i; b++)
{
printf("ptr[%d] --> %d\n", b, ptr[b]);
}
printf("\n");
i++;
}
int main()
{
int a;
while(1)
{
scanf("%d",&a);
push(a);
}
return 0; // main() expects you to return something, remember?
}
Each time you call push(), new memory is allocated to hold 10 integers. You are not doing anything to save the pointer to that memory.
This is called a memory leak, because you're allocating memory but you never free it. If you call push() enough times, you could run out of memory.
You must allocate only once. At the moment you are creating a memory leak each time you call the function push. Nobody refers to the memory once you leave the function. You can make it static to keep the information. Be aware that you are also limiting the number of values that you can hold at 10.
void push(int p)
{
static int i=0;
static int *ptr =(int *)malloc((10)*sizeof(int)); // To keep the values
int b;
ptr[i]=p;
for(b=0;b<=i;b++){
printf("%d",ptr[b]);
printf("\n");
}
i++;
if( i >= 10 ) i = 0; // To make sure there is no overflow
}
Better yet you could pass in the location where you want to save the information.
void push(int p, int *ptr)
{
static int i=0;
int b;
ptr[i] = b;
for(b=0;b<=i;b++){
printf("%d",ptr[b]);
printf("\n");
}
i++;
if( i >= 10 ) i = 0; // To make sure there is no overflow
}
int main()
{
int a;
int values[10];
while(1)
{
scanf("%d",&a);
push(a, values);
}
}