C pass array to a function by pointer - c

I am new to C and pointers and I'd like know if its possible to pass an array pointer to a function instead of passing the array of characters itself. I am posting the snippet from the code.
char ipAddress[24];
int i, j;
for (i = 12; i <= 13; i++)
{
for (j = 1; j <= 254; j++)
{
sprintf(ipAddress,"192.168.%d.%d",i,j);
runCommand(ipAddress);
}
}
// ...
int runCommand (char x[24])
{
// Do stuff.
}

Arrays are always passed by pointer in C, not passed by value (copyed)
So
int runCommand (char x[24]);
is close equivalent of
int runCommand (char *x);

Yes, it is possible to pass a pointer to an array to a function. No, it is probably not what you want.
int runCommand(char (*x)[24])
{
if ((*x)[0] == '\0') // Option 1
return -1;
if (x[0][0] == '\0') // Option 2: equivalent to option 1.
return -1;
...
}
void alternative(void)
{
char y[24] = "Samizdat";
printf("%d\n", runCommand(&y));
}
That says x is a pointer to an array of 24 characters. Be very careful, though. In general, you do not want to pass a pointer to an array; you just want to pass pointers around.
int runCommand(char x[24]) // Or: char *x
{
if (x[0] == '\0') // Option 1
return -1;
...
}
void alternative(void)
{
char y[24] = "Samizdat";
printf("%d\n", runCommand(y));
}

Related

C function doesn't modify passed array

Hi I need help with my C assignment. I need to modify a dynamic 2d array, so I pass a pointer to it to function, unfortunately it seems to not modify it but only copy it and leave it untouched, I have tried everything, can someone help please?
int getUniqueRelMembersCount(universe_t u, relation_t rel, char **members)
{
int memberCount = 0;
//count and dynamically populate passed 2d array with unique members of rel
return memberCount;
}
How I call the function:
char **members = malloc(sizeof(members));
int len = getUniqueRelMembersCount(universe, relations.relations[0], members);
printf("%d\n", len);
printf("%s", members[0]);
for (int i = 0; i < len; i++)
{
free(members[i]);
}
free(members);
output:
3
Segmentation fault
EDIT:
Ok, I tried to make a demo using your answer and I am still confused:
int populate(char ***members)
{
*members = malloc(sizeof(*members));
for (int i = 0; i < 3; i++)
{
char string[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
*members = realloc(*members, (i + 1) * sizeof(char *));
*members[i] = malloc(strlen(string) * sizeof(char));
strcpy(*members[i], string);
}
return 0;
}
int main()
{
char **members;
populate(&members);
printf("%s\n", members[0]);
printf("%s\n", members[1]);
printf("%s\n", members[2]);
return 0;
}
output:
Hello
đOu
(null)
It does modify the array. It might even free it. That's not the problem.
The problem is it also changes the pointer (members = realloc(...)), but you don't propagate this change to the caller. Despite having the same name, the variable named members in your function and the variable named members in the caller are different variables. After your realloc, the members variable in main might no longer be valid.
Simplified demo:
void f(int members) {
printf("%d\n", members); // 2
members = 3;
printf("%d\n", members); // 3
}
int main(void) {
int members = 2;
printf("%d\n", members); // 2
f(members);
printf("%d\n", members); // 2
return 0;
}
You could return the modified value. In this case, it's better to pass a pointer to the variable.
int f(int *membersPtr) {
printf("%d\n", *membersPtr); // 2
*membersPtr = 3;
printf("%d\n", *membersPtr); // 3
}
int main(void) {
int members = 2;
printf("%d\n", members); // 2
f(&members);
printf("%d\n", members); // 3
return 0;
}
In your full program, a pointer to the variable would have type char***.
Your following code shouldn't work:
char **members = malloc(sizeof(members));
int len = getUniqueRelMembersCount(universe, relations.relations[0], members);
because:
you cannot use 'member' value to initialize 'member';
malloc returns signle pointer, but not double pointer.
Try this:
int members_count = 10;
char *members = malloc(members_count);
int len = getUniqueRelMembersCount(universe, relations.relations[0], &members);

How do I do a word search without using strcmp?

int function(char * WordList[], int nSize, char * param_str)
{
int i = 0;
int bFlag = 0;
while(i < nSize && !bFlag)
{
if(WordList[i] == param_str){
return bFlag = 1;
}
i++;
}
return bFlag;
i tried using strcmp and made it work [if(strcmp(WordList[i], param_str) == 0)] but im wondering whats wrong with my current code.
WordList[i] is a pointer
param_str is another pointer.
WordList[i] == param_str tests if the 2 pointers point to the same location.
What these pointers reference is not considered. WordList[i] == param_str is not a string compare, just an address compare.
strcmp(a,b) compares the data at locations a and b.
To do the same, without strcmp(), form your own ...
int my_strcmp(const char *a, const char *b) {
// Pseudo code
while what `a` points to is the same as what `b` points to and `*a` is not 0
advance both pointers
return the sign of the difference of `*a` and `*b`.
}

Program keeps crashing

I'm new to C, and pointers for that sake, so some help would be wonderful. My program has crashed multiple times when I try to run this code.
My method punkt_paa_linje returns an integer, instead of a string, because of pointers I assume. I have a very vague understanding of pointers, so an explanation would be very appreciated
char punkt_paa_linje(int linje_1[3], int linje_2[3], int punkt[3])
{
int i;
double t1;
double t2;
double t3;
for(i = 0; i < 3; i = i + 1 ){
double t = (punkt[i]-linje_1[i])/linje_2[i];
if(i == 0){
t1 = t;
} else if (i == 1){
t2 = t;
} else if (i == 2){
t3 = t;
}
}
if(t1 == t2 && t2 == t3){
return "true";
} else {
return "false";
}
}
And when I call the function, it returns 36
int main()
{
int et[] = {1,2,3};
int to[] = {4,5,6};
int tre[] = {7,8,9};
printf("%d\n", punkt_paa_linje(et, to, tre));
return 0;
}
EDIT: The reason I didn't insert an error message is because there is none
You should use char *punkt_paa_linje(int linje_1[3], int linje_2[3], int punkt[3]) instead of char punkt_paa_linje(int linje_1[3], int linje_2[3], int punkt[3]).
And use printf("%s\n", punkt_paa_linje(et, to, tre));. Then your code will run perfectly and give output true.
otherwise try :
#include <stdio.h>
int punkt_paa_linje(int linje_1[3], int linje_2[3], int punkt[3])
{
int i;
double t1;
double t2;
double t3;
for(i = 0; i < 3; i = i + 1 ){
double t = (punkt[i]-linje_1[i])/linje_2[i];
if(i == 0){
t1 = t;
} else if (i == 1){
t2 = t;
} else if (i == 2){
t3 = t;
}
}
if(t1 == t2 && t2 == t3){
return 1;
}
else {
return 0;
}
}
int main()
{
int et[] = {1,2,3};
int to[] = {4,5,6};
int tre[] = {7,8,9};
printf("%d\n", punkt_paa_linje(et, to, tre));
return 0;
}
Output :
1
I will try to explain your mistakes.
You are trying to return string literal. Which has type const char* and its seqention of characters in static storage duration memory, like this
n n+1 n+2 n+3 n+4 <-- Addresses
+---+---+---+---+----+
|'t'|'r'|'u'|'e'|'\0'|
+---+---+---+---+----+
And you are trying to return this string via char, which is one byte in memory, like this
n
+---+
|'t'|
+---+
So you have to return string instead of char, where string is passed by pointer to first character in C.
const char * punkt_paa_linje(int linje_1[3], int linje_2[3], int punkt[3])
...
return "true";
%d specifier expects parameter of type int, while your function now returns string, which has specifier %s.
printf("%s\n", punkt_paa_linje(et, to, tre));
Arrays in C are passed as pointer, so instead of parameters int linje_1[3] use can simply use int * linje_1 or int linje_1[] - its same, and it will accept arrays of all lengths.
Here is live demo. Just click run :-)
You should call your function char *punkt_paa_linje, cause here it just return a char and you need a str, which is a char * type.
So if you really want your function to return a char call it char punkt_paa_linje
There are multiple things when returning string from function in c:-
1.Never return string local variable from function since all local variable of a function will be store in stack and stack will be destroy once function return so local varaible will be invalid now.
2.If you want to retrun string function either you should use:-
1.Heap memory.
2.static variable.
3.String constant literal.
In your example if you want to return string you should use char * as a return type of a function.
char * punkt_paa_linje()
In place of using %d in printf in your code use %s for printing string.
printf("%s\n", punkt_paa_linje(et, to, tre));

C pointer arithmetic palindrome

I'm a java student who's currently learning about pointers and C.
I tried to make a simple palindrome tester in C using a single array and pointer arithmetic.
I got it to work without a loop (example for an array of size 10 :*(test) == *(test+9) was true.
Having trouble with my loop. School me!
#include<stdio.h>
//function declaration
//int palindrome(int *test);
int main()
{
int output;
int numArray[10] = {0,2,3,4,1,1,4,3,2,0};
int *ptr;
ptr = &numArray[0];
output = palindrome(ptr);
printf("%d", output);
}
//function determine if string is a palindrome
int palindrome(int *test) {
int i;
for (i = 0; i <= (sizeof(test) / 2); i++) {
if (*(test + i) == *(test + (sizeof(test) - i)))
return 1;
else
return 0;
}
}
The Name of the array will itself acts as a pointer to an first element of the array, if you loose the pointer then there is no means for you to access the element of the array and hence you can send just the name of the array as a parameter to the function.
In the palindrome function:
you have used sizeof(test)/2. what happens is the address gets divided which is meaningless and hence you should not use that to calculate the mid element.
sizeof the pointer will be the same irrespective of the type of address that gets stored.
Why do you copy your pointer in another variable?
int *ptr;
ptr = &numArray[0];
Just send it to you function:
palindrome(numArray);
And sizeof(test) give you the memory size of a pointer, it's not what you want. You have to give the size in parameter of your function.
int palindrome(int *test, int size){
...
}
Finally your code must look like this:
#include<stdio.h>
int palindrome(int *test, int size);
int main()
{
int output;
int numArray[10] = {0,2,3,4,1,1,4,3,2,0};
output = palindrome(numArray, 10);
printf("%d", output);
}
//function determine if string is a palindrome
int palindrome(int *test, int size) {
int i;
for (i = 0; i < size / 2; i++) {
if (*(test + i) != *(test + (size - 1) - i))
return 0;
}
return 1;
}

Is this the right way to pass an array back from the function to main

The program is running without errors, but it stops after it runs this function since it seems that the array is not being passed back. Is this the right way to pass the array back to the function? I've included only the essential code below. Please could you point out where I might be wrong.
int matchedNumbersfunc(int lotoNumbers[],int ticketNumbers[], int *numbersRight);
int main()
{
int lotoNumbers[7];
int ticketNumbers[7];
int matchedNumbers[7];
int numbersRight = 0;
matchedNumbers[7] = matchedNumbersfunc(ticketNumbers, lotoNumbers, &numbersRight);
return 0;
}
int matchedNumbersfunc(int lotoNumbers[],int ticketNumbers[], int *numbersRight)
{
int matchedNumbers[7];
int i, k ,j;
*numbersRight = 0;
for(k=0;k<7;k++)
{
matchedNumbers[k] = 0;
}
for(i=0;i<7;i++)
{
for(j=0;j<7;j++)
{
if(ticketNumbers[i] == lotoNumbers[j])
{
matchedNumbers[i] = ticketNumbers[i];
}
}
if(matchedNumbers[i] != 0)
{
printf("You have a winning number: %d\n", matchedNumbers[i]);
*numbersRight = *numbersRight + 1;
if(matchedNumbers[6] != 0)
{
*numbersRight = *numbersRight - 1;
}
}
}
return matchedNumbers[7];
}
So, you are returning a single value rather than an array. And as it happens, you are returning a value off the end of the array, and assigning to a value off the end of another array. Your arrays have 7 elements, indexed 0 to 6.
What you need to do is pass an array to the function and let the function populate it. A simple example:
void foo(int array[], size_t count)
{
for (size_t i = 0; i < count; i++)
array[i] = i;
}
Which you would call like this:
int myArray[7];
foo(myArray, 7);
Another solution is to allocate a new array dynamically in your function and return a pointer to that array with this prototype:
int* matchedNumbersfunc(int lotoNumbers[],int ticketNumbers[], int *numbersRight);
Your revised function would start like this:
int* matchedNumbers;
int i, k ,j;
*numbersRight = 0;
matchedNumbers = (int*) calloc (7, sizeof(int));
if (matchedNumbers==NULL)
return NULL;
for(k=0;k<7;k++)
...
return (matchedNumbers);
In the main() you do not need to allocate the table, but just a pointer:
...
int *matchedNumbers;
...
matchedNumbers = matchedNumbersfunc(...);
if (matchedNumbers==NULL)
{ /* not enough memory - some kind of error processing */ }
free (matchedNumbers); // once you don't need the result anymore
return 0;
For your simple programme dynamic allocation could be overkill. But for more complex processing, this approach could be useful as well.

Resources