Character Pointer Arithmetic in Main vs In Other Functions [duplicate] - c

This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
C - modify the address of a pointer passed to a function
(6 answers)
Closed 5 years ago.
I am working on a practice problem that asks me to remove the first character in a string. Ex. char *string = "Rudolph", after calling removeFirst(string), string now equals "udolph".
I noticed, if I do it all in my main, I get the output "udolph". Here is my code:
int main() {
char *string = "Rudolph";
printf("%s\n", string);
//removeFirst(string);
string++;
printf("%s\n", string);
return 0;
}
However, if I were to call another function, my output is Rudolph. Here again is my code:
void removeFirst(char *string) {
if (string == "" | string == NULL)
return;
string++;
}
int main() {
char *string = "Rudolph";
printf("%s\n", string);
removeFirst(string);
//string++;
printf("%s\n", string);
return 0;
}
Given that I'm working with pointers, I thought that the changes I make in removeFirst should also make it to main. Why doesn't it work that way?

You are changing to the local variable. C is pass by value. A char* with same value as that of string is there in the called function removeFirst(). You make changes to it and then you expect the changes made on the copy to be reflected in the original variable. That's not going to happen here. That's why you don't get the same result as before case.
string == "" comparing two addresses not the content as you may have expected.
You can make changes like this
removeFirst(&string);
void removeFirst(char **string) {
if (*string == NULL)
exit(1);
(*string)++;
}
Then in main()
printf("%s\n", string); outputs udolph.
In this is case you pass the address of the pointer variable. You are now changing to the original variable by accessing the memory contained in the called function's local variable string. That is what retain the changes in main().

Related

Modifying a pointer in a function [duplicate]

This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 3 years ago.
I've made a function that allows the input of a string via keyboard. This function has two arguments: the maximum possible length of the string and a pointer to char. What happens inside the function is that an array of characters, which has as many elements as the maximum length, gets declared and then the string given by the user gets temporarly stored in that very array. Once the acquisition of the string is done, I use the calloc function to allocate just the right amount of memory to store that same string in the pointer to char that has been passed as an argument.
int main(void)
{
char* test;
stringInput(test, 10);
printf("%s", test);
return 0;
}
void stringInput(char* string, int maxStringLength)
{
char tempString[maxStringLength];
//STRING GETS PROPERLY STORED IN tempString
string = (char*)calloc(strlen(tempString)+ 1, sizeof(char));
strcpy(string, tempString);
return;
}
This sorts of work, meaning that if I try to print "string" before this function hits return, the program actually displays what it is supposed to. However, when I try to print "test" in the main function, it doesn't print anything, which means that stringInput isn't modifying the pointer that gets passed to it. I've further confirmed this by printing the address of "test" before the function call, after the calloc line and again after the function call, which showed me that it changes after the calloc but then gets back to its previous value when the function ends.
How can I solve this problem?
The problem here is, test itself is passed by value, which is stored in string, and any change you make to string will not reflect back to test.
You need to pass a pointer to test, if you want to modify test itself.
Something like
stringInput(&test, 10);
and
void stringInput(char** string, int maxStringLength)
{
char tempString[maxStringLength];
//STRING GETS PROPERLY STORED IN tempString
*string = calloc(strlen(tempString)+ 1, sizeof(char)); // no need to cast
if (!string) {
printf("error in calloc!!\n");
return;
}
strcpy(*string, tempString);
return;
}
When you calloc into string, you only modify the local copy of string, not the test variable. What you may want to do is pass in and operate on a pointer to your char pointer.
You could change you function signature to:
void stringInput(char **string_p, int maxStringLength)
Then, replace you usages of string with *string.
Finally, you would call your function passing in a pointer to test, not its value:
stringInput(&test, 10);
This is one way of doing things, though you could also return a pointer, depending on how you want to structure things.

Char array corrupted after its pointer is passed between functions [duplicate]

This question already has answers here:
Returning Local Variable Pointers - C [duplicate]
(1 answer)
Can a local variable's memory be accessed outside its scope?
(20 answers)
Capitalize string and return local variable
(3 answers)
Returning local variable from a function [duplicate]
(1 answer)
returning a local variable from function in C [duplicate]
(4 answers)
Closed 5 years ago.
I've been learning C for a few weeks. I have solved my problem by using malloc() to allocate some memory on the heap. I have an inkling about why my code failed but I'm not 100% sure. Unfortunately I am self-teaching so I have to turn to you kind people on the internet.
Code description Calls a function getString() which declares an array, fills the array using the inbuilt getchar() and returns a pointer to that array.
The issue I print the returned pointer value and everything is fine. BUT when I pass it to another function that simply spits it back out and try to print that, the end of the string is cut off, sometimes it spits out a nonsense character.
What I think could be happening The original array is only in use for as long as the getString() function & so C is using some of the memory in the array address to store other things.
Is my intuition correct? If not, could someone point me in the right direction?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 100
char * getString(void);
char * doSomethingWith(char *);
int main(void)
{
char *string1 = getString();
printf("String: %s\n", string1);
char *string2 = doSomethingWith(string1);
printf("String: %s\n", string2); // This print out is unreliable!
return EXIT_SUCCESS;
}
char * getString(void) {
int c;
char arr[MAXLEN];
char *string = arr;
char *cur = arr;
while((c = getchar()) != '\n' && c != EOF) {
if(cur - string < MAXLEN - 2) {
*cur++ = c;
}
}
*cur = '\0'; // Terminate string
return string;
}
char * doSomethingWith(char *string) {
return string;
}
Here is my amended getString() which behaves correctly.
char * getString(void) {
int c;
char *string = malloc(sizeof *string * MAXLEN);
char *cur = string;
while((c = getchar()) != '\n' && c != EOF) {
if(cur - string < MAXLEN - 2) {
*cur++ = c;
}
}
*cur = '\0'; // Terminate string
return string;
}
Update: Thanks for all the answers! Very much appreciated.
char *string = arr; is wrong because you did not allocate memory for arr; it is a variable on the stack. Upon return, the stack memory is relerased and so you return a pointer to a released variable.
Use malloc instead, e.g.:
string= malloc(strlen(arr)+1);
strcpy(string,arr);
return string;
getString returns the address of function local variable with automatic storage duration, the address of arr. Any attempt to access arr via that address after the function returns has undefined behavior.
There is no guarantee by the C standard it will preserve its value. There is no guarantee it won't. There is no obligation by the compiler to even produce a valid program when you break a language constraint like that.
6.2.4 Storage durations of objects ΒΆ2
The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address,33) and retains its last-stored value throughout its lifetime.34) If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.
The lifetime mentioned above is from the opening brace up to the closing brace of getString, for as long as its executing only. No more, no less.

C sizeof((x)) not working when I pass x as a pointer [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Miscalculation of array size inside a function
(3 answers)
Closed 6 years ago.
When I use the size of function in the main function it works correctly. However when i use it in the reverse function it only returns 8. Any ideas why or did i incorrectly use it.(This is the beginning of a assignment where I must reverse a string passed to the reverse function. I may only pass the string and nothing else and cannot use the string.h library. If there is another way to accomplish this please let me know. I was planning on using the sizeof function to get the size then looping through the array and use a temp variable to reverse it as I loop.)
#include <stdio.h>
char reverse(char *x);
int main(int argc, char* argv[])
{
char word[] = "Apple pies";
printf("%s\n", word);
reverse(word);
printf("%s\n", word);
printf("%s\n", reverse(word));
printf("%s\n", word);
return 0;
}
char reverse(char *x)
{
char crud;
int lc =0;
size_t length = 0;
char *tmp = x;
while (*tmp++)
++length;
while (length > lc)
{
crud = x[length];
x[length] = x[lc];
x[lc] =crud;
length--;
lc++;
}
}
In reverse, x is just a pointer (that is, a char*). But in main, x is an array (that is, a char[11]). That sizeof trick only works on arrays, not pointers. You'll have to pass the length to reverse as a parameter (or use strlen). This is covered in more detail in another question and its answers.
Since you say strlen is forbidden in your situation (as is passing in the length via a parameter), you'll have to implement strlen manually. It's trivial:
size_t length_of_str(const char *x) {
size_t length = 0;
while (*x++) ++length;
return length;
}
In the main method when you call the sizeof function, you are passing an array. But in the 'reverse' function, the argument is a character pointer. When you call sizeof on a pointer, there is no guaranteed result. Often you get 4 when you call sizeof on a char pointer. But again, there is no guarantee that sizeof will always return that value. You should not use sizeof for pointers.

C Unexpected string returned from function behaviour [duplicate]

This question already has answers here:
returning a local variable from function in C [duplicate]
(4 answers)
Closed 7 years ago.
I am quite new to C and I am playing with some string operations. I have encountered quite a strange problem for me while returning a string from a function. My simple program is as follows:
int main(int argc, char* argv[])
{
char text[] = "abAB";
char* out = testString(text);
printf("Result Text: %s", out);
printf("\n");
}
char* testString(char* input) {
char* text = copyString(input);
return text;
}
The copyString function defines a simple operation to copy one string to another. It is as follows:
char* copyString(char* input) {
char output[100];
int index = 0;
while (input[index] != '\0') {
output[index] = input[index];
index++;
}
output[index] = '\0';
return output;
}
The problem is that while I am debugging the application, the string I am returning from a function seems to be OK (Visual Studio visualises it well enough) and when the printf line occurs, the string outputted on the stdout is something completely strange and unfamiliar - a smily face. Sadly, I can't post images yet in order to show you what I see in my console as output.
I am using Visual C++ Express 2010 as an IDE if this could be helpful.
You are returning a variable declared within a function, which will cease to exist outside the scope in which it is declared. Use a dynamically allocated char array and then return a pointer to it.
char* output = malloc(100 * sizeof(char));
...
return output ;
Note : You are assuming that input string is less than 100 characters. Instead of that, try passing the length of string as a parameter or use strlen. Your program will crash if input string has more than 99 characters.
Also as noted in comments, free the memory allocated when you are done using it.

Returning string from function is not giving proper output [duplicate]

This question already has answers here:
returning a local variable from function in C [duplicate]
(4 answers)
Closed 7 years ago.
I'm trying to make a function which will receive a char * from the user and will print it.
It turns my value to something weird when I'm printing it.
**//input method**
char* readContactName(){
char tmp[20];
do{
printf("What is your contact name?: (max %d chars) ", MAX_LENGH);
fflush(stdin);
scanf("%s", &tmp);
} while (!strcmp(tmp, ""));
return tmp;
}
void readContact (Contact* contact)
{
char* tmp;
tmp = readContactName();
updateContactName(contact, tmp);
}
**//when entering this function the string is correct**
void updateContactName(Contact* contact, char str[MAX_LENGH])
{
printf("contact name is %s\n",&str); --> prints rubish
}
What did I miss here?
In your code, char tmp[20]; is local to the function readContactName(). Once the function finishes execution, there is no existence of tmp. So, the address-of-tmp also becomes invalid.
So, after returning, in the caller, if you try to use the returned pointer, (as you're doing in updateContactName(contact, tmp);()) it will invoke undefined behaviour.
FWIW, fflush(stdin); is also UB. fflush() is only defined for output streams.
Solution:
Define tmp as to be a pointer.
Allocate memory dynamically (using malloc() or family).
Once you're done using the allocated memory, you need to free() it also.

Resources