reallocating memory doesn't work in c - c

What I'm trying to do in my program is to copy the content of one string to another, in reverse. This part of the program works.
However, I don't want to limit the user for input, so I want to use malloc and realloc. This is my code:
#include <stdio.h>
#include <stdlib.h>
/*copy one string to another, in reverse*/
void copyStr(char *p, char *h){
int i=0,j=0;
int length=0;
length=strlen(p); int l=length;
for (i=0; i<length; i++){
h[i]=p[l-1];
l--;
}
char *temp=&h[0];
for (i=0; i<length; i++){
printf("%c",temp[i]);
}
}
main(){
printf("please enter a string\n");
char c; int i=0; int end=10;
/*allocate initial memory*/
char *p=(char*)malloc(sizeof(end)); char *temp=p;
while (c!='\n')
{
/*reallocate if needed*/
if (i==(end-1)){
end*=2;
temp = realloc(p,end*sizeof(temp));
if (temp!=NULL){
/*this is for myself, to see what the error was*/
printf("error allocating\n");
exit(1);
}
else
free(p);
}
c=getchar();
p[i]=c;
i++;
}
char h [sizeof(p)];
copyStr(p,h);
}
I found out that the realloc function doesn't work and so I am asking for your help.
The program works if the input is very short (i.e 3 chars).
If it longer than 10 letters, it will not reallocate memory.
If it longer than 5, it will print reversly but will send me a message called "stack smashed".
Thank you.

In fact, there are some little tricks to change :
the *temp=realloc(... should become temp=realloc(...
The fact that temp!=NULL is the normal behavior of realloc().
do not forget to change p after the realloc operation if you use it after.
sizeof(p) is the size of a pointer, that is 4 or 8... I turned it into char h [sizeof(char)*(i+1)];
i also added the \0 character at the end of the string. This is useful if you wish to print it or use strlen() and #include string.h. Then you can printf("the result is :\n%s \n",h);
Here goes the code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*copy one string to another, in reverse*/
void copyStr(char *p, char *h){
int i=0,j=0;
int length=0;
length=strlen(p); int l=length;
for (i=0; i<length; i++){
h[i]=p[l-1];
l--;
}
//keep end-of-string character
h[length+1]='\0';
/* char *temp=&h[0];
for (i=0; i<length; i++){
printf("%c",temp[i]);
}*/
printf("the result is :\n%s \n",h);
}
main(){
printf("please enter a string\n");
char c; int i=0; int end=10;
/*allocate initial memory*/
char *p=(char*)malloc(sizeof(end)); char *temp=p;
//signaling end of string
p[0]='\0';
while (c!='\n' && c!=EOF)
{
/*reallocate if needed*/
if (i==(end-2)){
end*=2;
temp=(char*)realloc(p,end*sizeof(char));
if (temp==NULL){
/*this is for myself, to see what the error was*/
printf("error allocating\n");
exit(1);
}
else{
p=temp;
printf("ok here\n");
}
}
c=getchar();
p[i]=c;
i++;
}
//signaling end of string
p[i+1]='\0';
printf("INVERTING STRING\n");
char h [sizeof(char)*(i+1)];
copyStr(p,h);
free(p);
}
! enif krow ot smees ti
Bye,
Francis

Its not *temp its temp. Realloc returns a address of the location where the memory is allocate which you should store in pointer . not storing in the address pointed by pointer already which would make no sense

*temp=(char*)realloc(p,end*sizeof(temp));
to be
temp = realloc(p,end*sizeof(temp));
The pointer is temp, *temp refers to content.

Related

Coding a string length function using pointer arithmetic

I'm in a beginner CS class learning C and we were tasked with coding a function to find string length using only string pointers. I have the following code:
#include <stdio.h>
int strlength(char* str);
int main() {
char *str;
int comp;
printf("Please enter the string: ");
scanf("%s", str);
printf("The length of the string is: %d\n", strlength(str));
return 0;
}
int strlength(char *str) {
int length = 0;
while(*str != '\0') {
length++;
str++;
}
return length;
}
I'm not really sure where I'm getting a segmentation fault. I've tried making a second pointer in the strlength function that equals str and incrementing that, but that also gives me a segmentation fault. Any insight would be appreciated!
char *str;
int comp;
printf("Please enter the string: ");
scanf("%s", str);
You should allocate memory in heap ( with malloc ) for *str before scanf. If you dont want to use malloc change it to char[number] so it can allocate memory in stack instead of heap

array changes when i change parameter

So i have this code in c.It all works fine until i get to the point to read word again.It gets the new word but also the (*A)[size-1] takes the price of the new word.How do i prevent this?
void fuction(char ***A,char ***B,int size)
{
char word[20],word2[20];
printf("Type word .\n");
gets(word);
while(strcmp(word,"0")!=0)
{
printf("Type second word.\n");
gets(word2);
printf("%d",size);
**A=realloc(**A,(size+1)*sizeof(char));
**B=realloc(**B,(size+1)*sizeof(char));
(*A)[size-1]=word;
(*B)[size-1]=word2;
size++;
printf("Type another word to add or 0 to exit.\n");//**it all works fine**
gets(word);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void function(char ***A, char ***B, int *size){
char word[32], word2[32];
printf("Type first word.\n");
scanf("%31s", word);
while(strcmp(word,"0")!=0){
printf("Type second word.\n");
scanf("%31s", word2);
*A =realloc(*A, (*size+1)*sizeof(char*));
*B =realloc(*B, (*size+1)*sizeof(char*));
(*A)[*size]=strdup(word);
(*B)[*size]=strdup(word2);
++*size;
printf("Type another word to add or 0 to exit.\n");
scanf("%31s", word);
}
}
int main(void){
int i, size = 0;
char **w1, **w2;
w1 = w2 = NULL;
function(&w1, &w2, &size);
for(i = 0; i < size; ++i){
printf("%s, %s\n", w1[i], w2[i]);
free(w1[i]);free(w2[i]);
}
free(w1);free(w2);
return 0;
}
Turns out the problem was that i didnt allocate memory for the words in the array.I added these lines and it worked.Thank you for your answers.
(*A)[size-1]=(char*) malloc(31);
(*B)[size-1]=(char*) malloc(31);
This
(*A)[size-1]=word;
(*B)[size-1]=word2;
is not what you think it is.
In c, this means you are assigning the address to the first element of the array word to (*A)[size-1] if you want this to work, provided that you have allocated memory for (*A)[size-1] you should do it this way
strcpy((*A)[size-1], word);
strcpy((*B)[size-1], word2);
You should think about why do you need char ***, generally you wont need more than char **, and don't use gets() use fgets() instead.

Print a string using putch with pointers in C

So I'm trying to print an inputted string using putch and a little bit of pointers.
Here is my current code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void printer(char *c);
char *c;
char ch;
main(){
clrscr();
printf("Enter a string: ");
scanf("%s",&ch);
c = &ch;
printer(c);
getch();
}
void printer(char *c){
int x;
for(x=0;x<strlen(c);x++){
putch(*c);
}
}
The problem is that i can only print the first character of the string, also for some reason strlen always return 3 for strings that are 3 characters and below.
Do I have to use array for this so that I can use putch since it is limited to only 1 character output.
One of the problems is that your printer() function is not printing anything other than the first character. There are two ways of approaching this. Using pointers:
void printer(char const *c){
while ( *c != '\0' ) {
putch(*c);
c++;
}
}
And using pointer arithmetic:
void printer(char const *c) {
int x;
for ( x=0; x < strlen(c); x++ ) {
putch( *(c + x) );
}
}
The biggest problem is that you are attempting to store a string in a single character in memory. That's just asking for problems.
char ch;
scanf("%s",&ch); // NO NO NO NO NO
Instead declare your buffer (to store the string in) as an array big enough for the biggest string you expect:
char ch[512];
scanf("%s", ch);
First off, you pass a pointer to "storage for one character" to scanf. Anything that happens after that is in nsal demons territory.
Second, scanf does not allocate storage for your input, so even if you'd passed c instead of &ch, you would not be any better off.
Third, you really should be declaring your variables inside main rather than using global variables.
Something like this may be closer to what you actually want:
void output (char *c)
{
char *cp;
for (cp = c; *cp; cp++) {
putch(*cp);
}
}
int main (void)
{
char input[80];
printf("Please input a string: ");
scanf("%s\n", input);
output(input);
}
try this code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void printer(char *c);
char *c;
char buffer[1000];// use as a buffer
void main(){
clrscr();
printf("Enter a string: ");
scanf("%s",buffer);//read the input to the buffer
c=(char*)malloc(strlen(buffer)+1);//alloc memory with len of input + 1 byte to "\0"(end of string)
strcpy(c,buffer);//copy the input from the buffer to the new memory
printer(c);
getch();
free(c);//free the memeory
}
void printer(char *c)
{
int x;
for(x=0;x<strlen(c);x++){//move the index string pointer to next char in the string
putch(c[x]);//print the char to the screen
}
}
1)You cant use char to save a string u need char*!!!
2)You can get input to memory that not allocated!!!! because of that u must read the input to buffer after that alloc string by size of the input inside the buffer!
Your code print only first character because c is always pointing to first character of the array. For printing total string you need to increment character pointer as well
You need to do like this
void printer(char *c){
while(*c != '\0'){
putch(*c);
c++;
}
}
First calculate the length of the string & then use above implementation like this-
void printer(char *c){
int i, length;
length=strlen(c)
for(i=0;i<lenth;i++,c++){
putch(*c);
}
}
It should work I think.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void printer(char *c);
char *c;
char ch;//the ch should be a array
main(){
clrscr();
printf("Enter a string: ");
scanf("%s",&ch);//the ch don't need '&'
c = &ch;//the ch don't need '&'
printer(c);
getch();
}
void printer(char *c){
int x;
for(x=0;x<strlen(c);x++){
putch(*c);
}
}

segmentation-error in ubuntu gcc

#include<stdio.h>
int main()
{
char *ch;
int n=10;
gets(ch);
puts(ch);
printf("%d\n",n);
}
#include<stdio.h>
int main()
{
char *ch;
int n=10;
gets(ch);
printf("%d\n",n);
puts(ch);
}
In the first one , the segmentation error occurs at print(n) and in second one it occurs at puts(ch).No error occurs if print(n) is also used just after declaring n.
gets() is dereferencing an unitialized pointer, causing undefined behaviour.
Allocate memory for ch and don't use gets() as there is no way to limit the number of characters read, meaning potentially writing beyond the bounds of the destination array.
Example using fgets():
char ch[128];
if (fgets(ch, 128, stdin))
{
}
Use fgets and allocate memory for your "buffer" (via malloc) to hold the given string. At the end call free for your pointer.
#include<stdio.h>
#include<stdlib.h>
int main(){
char * ch = (char*) malloc(sizeof(char)*10);
//or by using this: char ch[10];
int n=10;
gets(ch);
puts(ch);
printf("%d\n", n);
free(ch);
}

string rotations

#include <stdio.h>
#include <string.h>
int main()
{
char s[15];
int i,j,n,*str;
printf("Enter a string");
scanf("%s",str);
n=strlen(str);
for(i=0;i<n;i++)
{
str[n]=str[0];
for(j=0;j<n;j++)
{
str[j]=str[j+1];
}
str[n]='\0';
printf("\n %s",str);
}
return 0;
}
this program gives me all possible rotations of string
can anyone explain str[n]=str[0] and str[j]=str[j+1] meaning
instead of taking n=strlen(s) can we use n=strlen(str)
plz explain
This rotates the string. The way it does so is by moving the first character to the last place by doing str[n] = str[0] (str[n] is the string-terminating null character '\0', then shifting the whole string down one (str[j] = str[j+1]), then replacing the null at the end (str[n]='\0').
This code would, if it were using s, cause a buffer overrun if the string is longer than 14 characters. However, there's also a logic error in the code: it should be either initializing str (as a char* not int*) or scanning into s with a length bound. For instance:
scanf("%14s", s);
or
str = (char*)malloc(500);
scanf("%500s", str);
instead of taking n=strlen(s) can we use n=strlen(str)
Actually, since str is an int-pointer that is not initialized anywhere, all uses of str should be replaced by s (it's probably just a typo).
#include <stdio.h>
#include <string.h>
int main()
{
char s[15];
char tmp_var;
int i,j,n,*str;
printf("Enter a string");
scanf("%s",str);
n=strlen(str);
for(i=0;i<n/2;i++)
{
tmp_var = str[i];
str[i] = str[n-i];
str[n-i] = tmp_var;
}
printf("\n Rotated String is %s \n",str);
return 0;
}

Resources