Pass char pointer array to function - c

I'm trying to pass an initialized char pointer array to a function. I can't seem to figure out why the function will only print out the numeric digits of each element in the array.
Does anyone know how I can print each string element from the passed in pointer array?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
void sort(char *);
int main()
{
char *states[4] = {"Florida", "Oregon", "California", "Georgia"};
sort(*states);
return 0;
}
void sort(char *states)
{
int x;
for (x = 0; x < 4; x++) {
printf("\nState: %d\n", states[x]); //only this will compile
//printf("\nState: %s\n", states[x]); //need to print this.
}
}

Your sort function must accept the array of pointers if you wish to print the contents of the array.
void sort (char *states[], size_t num_states) {
int x;
for (x = 0; x < num_states; ++x) {
printf("\nState: %s\n", states[x]); /* Note %s instead of %d */
}
}
And, you must pass the array to the function.
sort(states, 4);

You need to parse an array of pointers to char to sort (instead of just pointer to char).
As jhx pointed out, you need to pass the size of the array as well. You can use sizeof so as to not hard-coding 4. Also omit the array size when initialize it.
void sort( char *states[], int arr_size )
{
int x;
for (x = 0; x < arr_size; x++)
{
printf( "\nState: %s\n", states[x] );
}
}
int main()
{
char *states[] = {"Florida", "Oregon", "California", "Georgia"}; // array of pointers to char
sort( states, sizeof( states ) / sizeof( char * ) );
return 0;
}

You need to pass the char pointer array to the function:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
void sort(char *args[], int n);
int main()
{
char *states[4] = {"Florida", "Oregon", "California", "Georgia"};
sort(states, 4);
return 0;
}
void sort(char *states[], const int N)
{
int x;
for (x = 0; x < N; x++) {
printf("\nState: %s\n", states[x]);
}
}

The reason that only numeric values you are getting is that only pointer to first element of string states[0] of the array states is passed, i.e. you are passing &states[0][0]. So, the statement
printf("\nState: %d\n", states[x]);
will only print the numeric value of first 4 characters of string "Florida".
You need to pass the pointer to first element of array states, i.e. &states[0].
This can be done by changing the declarator of function sort to
void sort(char **, size_t size); // You need to pass the size of array too.
and call it as
sort(states, sizeof(states)/sizeof(char *));

You're sending states which is an array of pointers. So you need to send the base address of that array to the function
sort(*states);
And then receive it in an array of pointer only
void sort(char* states[])
{
int x;
for (x = 0; x < 4; x++) {
printf("\nState: %s\n", states[x]);
}
}
Hardcoding the size if also not a good idea, so better add another parameter size to the function call.
sort(states, sizeof(states)/sizeof(char*));
and later use that to iterate over the array
void sort(char* states[], int size)
{
int x;
for (x = 0; x < size; x++) {
printf("\nState: %s\n", states[x]);
}
}

Related

dynamic arrays int printing problem - maybe not a valid memory cell

#include <stdio.h>
#include <stdlib.h>
int find_lenght(int *arrr){
int i = 0;
while(arrr[i] != '\0'){
i++;
}
return i;
}
void init_array(int *arrr){
arrr=(int*)malloc(1*sizeof(int));
printf("New element:");
int lenght = find_lenght(arrr);
scanf("%d", &arrr[lenght]);
printf("Lenght = %d\n",lenght);
printf("Array elements are:\n");
for(int i = 0; i <= lenght; i++) {
printf("%d,", arrr[i]);
}
}
void print_array(int *arrr){
printf("Array elements are:\n");
int lenght = find_lenght(arrr);
for(int i = 0; i == lenght; i++) {
printf("%d,", arrr[i]);
}
}
int main() {
int *arr = NULL;
init_array(arr);
print_array(arr);
}
I don't know what am i missing here.
My point is to fill in and then print dynamic array
Also my taught is it's not filling the way it should, so it hasn't anything to print.
Your arr pointer in main is never assigned because your init_array assign the address of the allocated memory (the return value of malloc) to the input parameter arrr, which is, a local variable.
You have mainly two solutions to properly achieve what you want to do. The first one (the better one in my point of view), by making your init_array returning the allocated memory address to be assigned:
int* init_array()
{
int* retval = (int*)malloc(1*sizeof(int));
// ...
return retval;
}
int main()
{
int *arr = init_array(); //< assign arr with returned value
}
Another way is to make your init_array function taking a pointer to a pointer, so the function can assign this pointer:
void init_array(int** arrr)
{
(*arrr) = (int*)malloc(1*sizeof(int));
// ...
}
int main()
{
int* arr = NULL;
init_array(&arr); //< pass reference to arr
}
You need to pass the pointer to pointer to int to change passed pointer. Your for loop is invalid in print function. You need also to set the sentinel value yourself.
size_t find_length(const int *arrr)
{
size_t i = 0;
if(arrr)
while(arrr[i]) i++;
return i;
}
void add_element(int **arrr, int element)
{
size_t length = find_length(*arrr);
int *tmp = realloc(*arrr, (length + 2) * sizeof(**arrr));
if(tmp)
{
*arrr = tmp;
(*arrr)[length] = element;
(*arrr)[length + 1] = 0;
}
}
void print_array(const int *arrr)
{
printf("Array elements are:\n");
size_t lenght = find_length(arrr);
for(size_t i = 0; i < lenght; i++)
{
printf("arrr[%zu] = %d\n", i, arrr[i]);
}
}
int main(void) {
int *arr = NULL;
add_element(&arr, 5);
add_element(&arr, 15);
add_element(&arr, 25);
add_element(&arr, 35);
print_array(arr);
}
https://godbolt.org/z/drKej3KT5
the array on your main function is still NULL. the better way to do is just call the print_array() function after you initialize it. you just simply put print_array(arrr) inside init_array() and after the for loop statement.
The line
int lenght = find_lenght(arrr);
may invoke undefined behavior, because find_length requires its argument to be a pointer to the first element of a null-terminated int array. However, the content of the memory pointed to by arrr is indeterminate, because it has not been initialized. Therefore, it is not guaranteed to be null-terminated.

what is the issue with copyArray func in this c program ? the copyArray function is not working properly

** I would like to copy the pointer array to a new pointer so the original array won't change**
/* The main contains a pointer (p) to an array */
int main()
{
...
...
...
p = (int*)malloc(length*sizeof(int));
z = (int*)copyArray(p, length);
printArray(z, length);
return 0;
}
/* end of main */
CopyArray func
/* copy the array, return a new pointer to a new array with same size and values */
int copyArray(int *p, int length)
{
int *z = (int*)malloc(length*sizeof(int));
for(length--; length>=0; length--)
{
z[length] = p[length];
}
return *z;
}
printArray func
/* The function receives a pointer to an array and it's length. it will print the values that the array contains by the order */
void printArray(int *p, int length)
{
int i = 0;
for(; i<length; i++)
{
printf("\n %d \n", p[i]);
}
}
Reason for not working : return *z; here you are returning only one element *(z+0) = z[0] not the whole array. Check the code below:
#include <stdio.h>
#include <stdlib.h>
int *copyArray(int *p, int length) // Change return type to `int *`
{
int *z = malloc(length * sizeof(int)); // No need to cast output of malloc
for (length--; length >= 0; length--)
{
z[length] = p[length];
}
return z; // return the pointer.
}
void printArray(int *p, int length)
{
int i = 0;
for (; i < length; i++)
{
printf("\n %d \n", p[i]);
}
}
int main()
{
int *p;
int *z;
int length =5;
p = malloc(length*sizeof(int)); // No need of casting
for(int i=0 ;i<length; i++)
{
p[i] = i; // assigning some values
}
z = copyArray(p, length); // Donot cast return of the function
printArray(z, length);
return 0;
}
The output is :
0
1
2
3
4

use of undeclared identifier 'arr'

I'm trying to have some practice with C using Xcode, but got stock with some error.
The code is as follows:
#include <stdio.h>
#include <stdlib.h>
/* move previous elements down until insertion point reached */
void shift_element (unsigned int i ) {
int ivalue;
// guard against going outside array
for (ivalue = arr[i]; i && arr[i-1] > ivalue; i--) {
arr[i] =arr[i-1]; // move element down
arr[i] = ivalue; // insert element
}
}
int main(int argc, const char * argv[]) {
unsigned int arr[5] = {2,4,5,3,6};
shift_element(3);
// print arr
int i;
for (i=0;i < (sizeof (arr) /sizeof (arr[0]));i++) {
printf("%d\n",arr[i]);
}
return 0;
}
But it results in an error saying 'use of undeclared identifier 'arr''
I searched previous questions with the same subject but could not find a proper answer that would solve my problem.
I would be so happy if somebody can help.
Cheers
The arr variable isn't in scope of the shift function. You have to pass it in as a parameter.
You forgot to declare your 'arr'.
Here is a very good answer explaining the various way do to that : How to initialize all members of an array to the same value?
EDIT : Didn't see you declared it in the function below. As the other answer says, you have to pass it as a parameter tho.
Your problem lies in variable accessibility. When you define a variable in the main function it is only accessible in the function in which it was defined. You to try access the array in the shift_elements function which is causing your issue.
To fix this you can either make the arr variable global or pass it in as an argument to your shift_elements(function). I coded a quick correction doing the later because its good practice to avoid global variables when possible.
#include <stdio.h>
#include <stdlib.h>
/* move previous elements down until insertion point reached */
void shift_element (unsigned int i, int[] arr) {
int ivalue;
// guard against going outside array
for (ivalue = arr[i]; i && arr[i-1] > ivalue; i--) {
arr[i] =arr[i-1]; // move element down
arr[i] = ivalue; // insert element
}
}
int main(int argc, const char * argv[]) {
unsigned int arr[5] = {2,4,5,3,6};
shift_element(3, arr);
// print arr
int i;
for (i=0;i < (sizeof (arr) /sizeof (arr[0]));i++) {
printf("%d\n",arr[i]);
}
return 0;
}
For more information on types of variables look here: http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/kinds-vars.html
Just to share with those future possible readers, the correct code would be:
#include <stdio.h>
#include <stdlib.h>
/* move previous elements down until insertion point reached */
void shift_element (unsigned int i, unsigned int *arr ) {
int ivalue;
// guard against going outside array
for (ivalue = arr[i]; i && arr[i-1] > ivalue; i--)
arr[i] = arr[i-1]; // move element down
arr[i] = ivalue; // insert element
}
int main(int argc, const char * argv[]) {
unsigned int arr[5] = {2,4,5,3,6};
// print arr
int i;
for (i=0;i < (sizeof (arr) /sizeof (arr[0]));i++) {
printf("%d\n",arr[i]);
}
shift_element(3, arr);
// print arr
for (i=0;i < (sizeof (arr) /sizeof (arr[0]));i++) {
printf("%d\n",arr[i]);
}
return 0;
}

Can you return a type of pointer to pointer in a function?

I know you can return a type of pointer from a function.
ex. void *foo()
Can you return a type of pointer to pointer in a function?
ex. void **foo2()
Here is more info about my question:
I try to assign a ptr-to-ptr, tmp2, to blocks[i][j], and then return tmp2. blocks[i][j] is a ptr-to-ptr as well.
I'm confused to manipulate a ptr to a ptr-to-ptr: I am not sure if return ((tmp2+i)+j); is the cause of the segmentation fault at line printf("2---%d\n", **tmpPtr2);. To debug, I try to print: printf("%d\n", *( (*(tmp2+i)) +j) ); However, it causes a new segmentation fault.
#include <stdio.h>
#include <stdlib.h>
int **blocks, **tmp2;
int n = 10;
int **findBlock2(int b){
int i, j ;
for (i=0; i<n; i++){
for (j=0; j<n; j++){
if (blocks[i][j]==b){
printf("%d\n", blocks[i][j]);
//Segmentation fault
printf("%d\n", *((*(tmp2+i))+j) );
return ((tmp2+i)+j);
}
}
}
return NULL;
}
int main(int argc, const char * argv[]) {
int i, j;
int **tmpPtr2;
//allocate memory space and assign a block to each index
blocks=malloc(n * sizeof *blocks);
for (i=0; i<n; i++) {
blocks[i]=malloc(n * sizeof(*blocks[i]));
blocks[i][0]=i;
}
if ((tmpPtr2=findBlock2(4))==NULL) return -1;
//Segmentation Fault
printf("2---%d\n", **tmpPtr2);
return 0;
}
Update to answer my question:
(1) Adding ttmp2=blocks; to the top of findBlock2() removed both segfaults.
(2) return ((tmp2+i)+j); shows how to manipulate a ptr-to-ptr pointing to a ptr-to-ptr or a 2D array
(3) printf("%d\n", *( (*(tmp2+i)) +j) ); shows how to do (2) and dereference it.
Hope it helps others
Yeah, just like you would with any pointer variables.
#include <stdio.h>
#include <stdlib.h>
int ** function(){
int ** matrix = malloc(sizeof(int*));
*matrix = malloc(sizeof(int));
matrix[0][0] = 5;
return matrix;
}
int main()
{
int **matrix = function();
printf("%d",matrix[0][0]);
free(matrix[0]);
free(matrix);
return 0;
}
Adding to the other part. In your function findBlock2 besides accessing an invalid reference that has already been pointed out, it seems that your objective is to return a reference to the block that fulfills if statement. If that is the case then returning a pointer to int* should suffice.
int *findBlock2( int b )
/////////////////
return ( *(blocks+i)+j );
You probably want a 2D array at not some slow, fragmented lookup table. In that case, do like this:
#include <stdlib.h>
void* alloc_2D (size_t x, size_t y)
{
return malloc (sizeof (int[x][y]));
}
int main (void)
{
const size_t X = 5;
const size_t Y = 3;
int (*arr_2D)[Y] = alloc_2D(X, Y);
// X dimension was omitted in declaration to make array syntax more intuititve:
arr_2D[i][j] = something;
...
free(arr_2D);
}
The answer is "yes". Please refer the following code:
#include <stdio.h>
#include <malloc.h>
void ** foo2(void){
int **p = malloc(sizeof(*p));
return (void**)p;
}
int main(void) {
printf("%p\n", foo2());
return 0;
}
The result is (in my 32-bit platform):
0x80e9008

Modifying a array in a function in C

#include <stdio.h>
#include <stdlib.h>
void array_tester(int *array);
int main(int argc,char *argv[])
{
int test[] = {1,1,1,1};
int print;
for(print = 0; print < sizeof(test) / sizeof(int); print++)
{
printf("%d\n",test[print] );
}
array_tester(test);
for(print = 0;print < sizeof(test)/sizeof(int);print++)
{
printf("%d\n",test[print] );
}
return EXIT_SUCCESS;
}
void array_tester(int array[])
{
int i ;
for(i = 0; i < sizeof(array) / sizeof(int); i++)
{
array[i] = i;
}
}
The problem is I want to modify the the array in the array_tester function but I'm unable to do so. What do I use inside sizeof()?
You have to manually pass the information about the size of the array.
void array_tester( int* array , int size ) ;
And then call it:
array_tester( test , sizeof(test)/sizeof(*test) ) ;
The reason behind this is that array passed to a function will decay to a pointer and the sizeof will return the size of pointer not the original array.

Resources