LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-21-2018, 08:15 AM   #1
jose_spain
LQ Newbie
 
Registered: Apr 2018
Posts: 10

Rep: Reputation: Disabled
Segmentation fault when I pass a char pointer to a function.


I am passing a char* to the function "reverse" and when I execute it with gdb I get:

Program received signal SIGSEGV, Segmentation fault.
0x000000000040083b in reverse (s=0x400b2b "hello") at pointersExample.c:72
72 *q = *p;


Attached is the source code.

I do not understand why this error occurs.

Why "modifyStruct" and "modifyString" are working right, but "reverse" does not work?

SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct book
{
char* title;
int pages;
float price;
};


void modifyInt (int *li)
{
*li *= 2;
}


void modifyStruct (struct book* lb)
{
char* newTitle = "The best book";

free(lb->title);
lb->title = malloc((strlen(newTitle) + 1) * sizeof(char));
strcpy(lb->title, newTitle);

lb->pages=350;
lb->price=20.25;
}


void modifyString (char* lw)
{
int i;
int strLen = strlen(lw);

for (i=0; i<strLen; i++)
if( (*(lw+i) >= 97) && (*(lw+i) <= 122) )
*(lw+i) -= 32; // Converts letters to upper case.
}


void reverse (char* s)
{
char* aux;
char* p;
char* q;

p = s;
int len = strlen(s);
aux = (char*) malloc ((len + 1) * sizeof(char));

printf("s=%s\n", s);

printf("strlen(s)=%d\n", len);
*(aux+len) = 0; // End string mark.
len--;
while (*p != 0)
{
*(aux+len) = *p;
len--;
p++;
}
printf("aux=%s\n", aux);

// Copy aux to s.
p = aux;
q = s;
while (*p != 0)
{
*q = *p;
p++;
q++;
}

printf("aux=%s\n", aux);
printf("s=%s\n", s);
}


int main()
{
int iv = 10;
struct book *mynewbook;
int len;
char* words1;
char* initial_words = "hello_pleased_to_met_you" ;
char* tmp = "hello";

printf ("\niv = %d\n", iv);
modifyInt(&iv);
printf ("After calling modifyInt, iv = %d\n\n", iv);

mynewbook = (struct book*)malloc (sizeof (struct book));
if (mynewbook == NULL)
return -1;

len = strlen("Unknown");
mynewbook->title = (char*) malloc ((len + 1) * sizeof(char));
strcpy(mynewbook->title, "Unknown");
mynewbook->pages=0;
mynewbook->price=0.0;
printf ("mynewbook: title = %s, pages=%d, price=%f\n",
mynewbook->title, mynewbook->pages, mynewbook->price);
modifyStruct(mynewbook);
printf ("After calling modifyStruct: mynewbook: title = %s, pages=%d, price=%f\n\n",
mynewbook->title, mynewbook->pages, mynewbook->price);

len = strlen(initial_words);
words1 = (char*) malloc ((len + 1) * sizeof(char));
strcpy(words1, initial_words);
printf ("words1 = %s\n", words1);
modifyString(words1);
printf ("After calling modifyString: words1 = %s\n\n", words1);

printf("tmp=%s\n" , tmp);
reverse(tmp);
printf("After calling reverse: tmp=%s\n\n" , tmp);

return 0;
}
 
Old 04-21-2018, 08:30 AM   #2
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (current), FreeBSD, Win10, It varies
Posts: 9,952

Rep: Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148
direct assignment does not work: replace with this and see what that does for you:
Code:
// Copy aux to s.
p = strdup(aux);
q = strdup(s);
/*
p = aux;
q = s;
* */
or this
Code:
void reverse(char str1[], int index, int size)

{

    char temp;

    temp = str1[index];

    str1[index] = str1[size - index];

    str1[size - index] = temp;

    if (index == size / 2)

    {

        return;

    }

    reverse(str1, index + 1, size);

}
source:
https://www.sanfoundry.com/c-program...g-recursion-2/
if you use that function then just mod your tmp changing it to an array then add the needed information in the prams and it works,(for me anyways, either one.).

Code:
$ ./a.out

iv = 10
After calling modifyInt, iv = 20

mynewbook: title = Unknown, pages=0, price=0.000000
After calling modifyStruct: mynewbook: title = The best book, pages=350, price=20.250000

words1 = hello_pleased_to_met_you
After calling modifyString: words1 = HELLO_PLEASED_TO_MET_YOU

tmp=hello
s=hello
strlen(s)=5
aux=olleh
aux=olleh
s=hello
After calling reverse: tmp=hello
Notice the use of code tags and how nice and easier it makes it to read.

Last edited by BW-userx; 04-21-2018 at 08:53 AM.
 
1 members found this post helpful.
Old 04-21-2018, 08:50 AM   #3
jose_spain
LQ Newbie
 
Registered: Apr 2018
Posts: 10

Original Poster
Rep: Reputation: Disabled
Thanks, but I want to understand pointers use and this is the reason that I do it with a pointer.

As you can see on my source code, when I copy s to aux, pointers are used and it works fine. This is the extract of the source code in "reverse":


char* aux;
int len = strlen(s);

*(aux+len) = 0; // End string mark.
len--;
while (*p != 0)
{
*(aux+len) = *p;
len--;
p++;
}
printf("aux=%s\n", aux);


When s is "hello", aux becomes "olleh". This works with pointers directly.

Why I can not change the pointer used as input parameter in "reverse" function, that is,
the s pointer?
 
Old 04-21-2018, 09:03 AM   #4
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 16,267

Rep: Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460
you might want to run it using ddd, that may help you to find the reason.
 
1 members found this post helpful.
Old 04-21-2018, 09:11 AM   #5
jose_spain
LQ Newbie
 
Registered: Apr 2018
Posts: 10

Original Poster
Rep: Reputation: Disabled
Thanks,

I have done new tests with this program and I have found that:

1) If tmp is declared and initialized in main so, it works right without changes in "reverse" function:

char* tmp;

tmp = (char*) malloc ((strlen("hello") + 1) * sizeof(char));
strcpy(tmp, "hello");
printf("tmp=%s\n" , tmp);
reverse(tmp);
printf("After calling reverse: tmp=%s\n\n" , tmp);


The program prints:

tmp=hello
After calling reverse: tmp=olleh

2) If instead I do this:

char* tmp = "hello";

printf("tmp=%s\n" , tmp);
reverse(tmp);
printf("After calling reverse: tmp=%s\n\n" , tmp);

Then I get the segmentation fault.

What is the difference?

In this second case, If I check the value of s in reverse, it is:
"hello" + 0 (end of string mark)
 
Old 04-21-2018, 09:23 AM   #6
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 16,267

Rep: Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460Reputation: 5460
because the string "hello" is a constant, you are not allowed to change that.
 
1 members found this post helpful.
Old 04-21-2018, 09:24 AM   #7
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (current), FreeBSD, Win10, It varies
Posts: 9,952

Rep: Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148
How to Reverse String using Pointer in C Might help.

if you'e wanting to try this one change the gets to fgets

fgets(str,len,stdin);

Last edited by BW-userx; 04-21-2018 at 09:28 AM.
 
1 members found this post helpful.
Old 04-21-2018, 09:34 AM   #8
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (current), FreeBSD, Win10, It varies
Posts: 9,952

Rep: Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148
Quote:
Originally Posted by jose_spain View Post
Thanks,

I have done new tests with this program and I have found that:

1) If tmp is declared and initialized in main so, it works right without changes in "reverse" function:

char* tmp;

tmp = (char*) malloc ((strlen("hello") + 1) * sizeof(char));
strcpy(tmp, "hello");
printf("tmp=%s\n" , tmp);
reverse(tmp);
printf("After calling reverse: tmp=%s\n\n" , tmp);


The program prints:

tmp=hello
After calling reverse: tmp=olleh

2) If instead I do this:

char* tmp = "hello";

printf("tmp=%s\n" , tmp);
reverse(tmp);
printf("After calling reverse: tmp=%s\n\n" , tmp);

Then I get the segmentation fault.

What is the difference?

In this second case, If I check the value of s in reverse, it is:
"hello" + 0 (end of string mark)
pin point where that segfault is happening so you can trouble shoot it. It's up in your function in the middle area. hint hint.

https://www.cs.bu.edu/teaching/cpp/string/array-vs-ptr/

this here does nothing for s or aux even if you where to get it to work.
Code:
// Copy aux to s.
p = aux;
q = s;
while (*p != 0)
{
*q = *p;
p++;
q++;
}
it is just acting on p and q only.

you never give the results back to what you're wanting to copy to.

MODDED

Code:
char * reverse (char* s)
{
char* aux;
char* p;
char* q;

p = s;
int len = strlen(s);
aux = (char*) malloc ((len + 1) * sizeof(char));

printf("s=%s\n", s);

printf("strlen(s)=%d\n", len);
*(aux+len) = 0; // End string mark.
len--;
while (*p != 0)
{
*(aux+len) = *p;
len--;
p++;
}

return aux;    
}

//in main
printf("After calling reverse: tmp=%s\n\n" , reverse(tmp));

Last edited by BW-userx; 04-21-2018 at 10:04 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Returning char pointer from function which has array of char pointer srinietrx Programming 3 10-30-2015 03:55 AM
[SOLVED] How can i pass an entire Array into a function parameter by value? (no pointer pass) esgol Programming 26 07-31-2012 11:34 AM
C : Function to modify pointer to char introuble Programming 2 06-21-2006 12:24 PM
Segmentation fault with char* array simopal6 Programming 8 06-16-2006 01:05 PM
c char* pointer function question true_atlantis Programming 9 04-14-2006 01:29 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:13 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration