I am getting a runtime error in this and i can't seem to figure it out.
This is my code to reverse a string and change A to T and vice-versa and to change C to G and vice-versa,
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* reverse(char *input)
{
int len=strlen(input);
char *rev=NULL;
rev=(char*)malloc(sizeof(char)*len);
int i,k=0;
for(i=len-1;i>=0;i--)
{
rev[k++]=input[i];
if(rev[k-1]=='A')
rev[k-1]='T';
else if(rev[k-1]=='T')
rev[k-1]='A';
else if(rev[k-1]=='C')
rev[k-1]='G';
else if(rev[k-1]=='G')
rev[k-1]='C';
}
rev[k]='\0';
return rev;
}
int main()
{
char *input=(char *)malloc(sizeof(char)*1000);
scanf("%s",input);
char *str =NULL;//(char*)malloc(sizeof(char)*1000);
str=reverse(input);
printf("%s",input);
free(input);
}
You do not allocate enough memory to hold your reversed string:
int len=strlen(input);
...
rev=(char*)malloc(sizeof(char)*len);
...
rev[k]='\0';
You missed 1 extra byte for the terminating \0.
And by the way... Please don't cast the return value from malloc to a pointer.
First of all, you use i++ instead of i-- in the for loop. That means that the for loop never ends and k gets very very big and your rev[k] atempts to access values that it shouldnt.
Secondly, you do not need to allocate memory for str, because you allocate it in the function.
And you should allocate memory for one more char in the function as you will need if for '\0'.
Related
I am attempting to copy a character from an array to a character pointer by means of a function. Following is my code:
#include<stdio.h>
void pass(void* arg){
char arr[1];
arr[0]='X';
memcpy((char *)arg,arr,1);
}
void main(){
char *buf=malloc(sizeof(char));
pass(buf);
printf("%c",buf);
free(buf);
}
Here, the pointer buf prints a garbage value. I tried the reverse of the above program as follows:
#include<stdio.h>
void pass(void* arg){
char arr[1];
memcpy(arr,(char *)arg,1);
printf("%c",arr[0]);
}
void main(){
char *buf=malloc(sizeof(char));
buf[0]='X';
pass(buf);
free(buf);
}
This was successful and arr[0] prints the value as X.
Could someone clarify why does the first case fail?
You have to print *buf or buf[0] instead of buf to print the first element of the array pointed by buf.
Also note that passing data having type char* to be printed via %c in printf(), which expect data having type int, is undefined behavior due to type mismatch.
Try this:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void pass(void* arg){
char arr[1];
arr[0]='X';
memcpy((char *)arg,arr,1);
}
int main(void){
char *buf=malloc(sizeof(char));
pass(buf);
printf("%c",buf[0]);
free(buf);
return 0;
}
Your problem lies here:
char *buf=malloc(sizeof(char));
:
printf("%c",buf);
because buf is a pointer to a character, not a character. The character is *buf, or buf[0] so you can fix it with:
printf ("%c", *buf);
As an aside, it's totally unnecessary to create arr and call memcpy in the first example when you can simply do:
void pass (void* arg) {
((char*)arg)[0] = 'X';
}
Dynamic memory allocation for a character in this case is also unnecessary when you can just replace the malloc line with a simple:
char buf[1];
(and get rid of the free line, of course).
I have encountered so called cryptic realloc invalid next size error , I am using gcc on linux my code is
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int i;
char *buf;
char loc[120];
buf = malloc(1);
int size;
for(i=0;i<1920;i++)
{
sprintf(loc,"{Fill_next_token = my_next_token%d; Fill_next_token_id = my_next_token_id = my_next_token_id%d}",i,i);
size = strlen(buf)+strlen(loc);
printf("----%d\n",size);
if(!realloc(buf,size))
exit(1);
strcat(buf,loc);
}
}
(mine might be duplicate question) here the solution somewhere lies by avoiding strcat and to use memcpy , But in my case I really want to concatenate the string . Above code works for good for such 920 iterations but in case 1920 realloc gives invalid new size error. Please help to find alternative of concatenating , looking forward to be a helpful question for lazy programmers like me .
Your code has several issues:
You are not accounting for null terminator when deciding on the new length - it should be size = strlen(buf)+strlen(loc)+1;
You are ignoring the result of realloc - you need to check it for zero, and then assign it back to buf
You do not initialize buf to an empty string - this would make the first call of strlen produce undefined behavior (i.e. you need to add *buf = '\0';)
Once you fix these mistakes, your code should run correctly:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
int i;
char *buf= malloc(1);
*buf='\0';
char loc[120];
for(i=0;i<1920;i++) {
sprintf(loc,"{Fill_next_token = my_next_token%d; Fill_next_token_id = my_next_token_id = my_next_token_id%d}",i,i);
int size = strlen(buf)+strlen(loc)+1;
printf("----%d\n",size);
char *tmp = realloc(buf,size);
if(!tmp) exit(1);
buf = tmp;
strcat(buf, loc);
}
}
Demo.
buf is not a valid string so strcat() will fail since it expects a \0 terminated string.
If you want to realloc() buf then you should assign the return value of realloc() to buf which you are not doing.
char *temp = realloc(buf,size+1);
if(temp != NULL)
buf = temp;
Point 1. Always use the return value of realloc() to access the newly allocated memory.
Point 2. strcat() needs a null-terminating string. Check the first iteration case.
#include<stdio.h>
int main(){
char *q;
int i=0;
do{
*(q+i)=getchar();
i++;
}while(*(q+i)!=48);
int j=0;
for(;j<i;j++)
printf("%c",*(q+j));
}
I try to use in this way. I could compile. However ıt does not work .
My aim is that I wanna acquire char array (unlimited or limit will be defined by the user)
What should I do?
You should read a book on C.
You're just writing into random memory, causing undefined behavior.
You must allocate memory, you can't just write through a non-initialized pointer!
For instance, make it:
char buffer[1024], *q = buffer;
Then make sure you don't overstep inside the loop, of course.
Also, there's no point in writing the access as *(p + i), when p[i] means the exact same thing and is much easier to read.
Finally, remember that technically getchar() returns int, since it can return EOF which is not a character.
1st allocate memory for your pointer *q
include<stdio.h>
int main()
{
int a;
char b[100];
int i=0;
char *p=b;
while((a=getchar())!=EOF)
{
p[i++]=a;
}
p[i+1]='\0';
printf("%s",b);
}
Also you can try heap memory allocation
char *p=(char*)malloc(40);
While doing some programs on strings, I have come across this little problem.
The question which was asked to me was this -
Write a pointer version of the function strcat(s,t) which copies the string t to the end of s.
I wrote the program as this -
#include<stdio.h>
void strcat(char *s, char *t);
int main()
{
char *s1, *s2;
printf("enter the first string\n");
scanf("%s",s1);
printf("Enter the second string\n");
scanf("%s",s2);
strcat(s1,s2);
printf("Strings concatenated\n");
printf("%s",s1);
return 0;
}
void strcat(char *s, char *t)
{
while(*s++)
;
while(*s++ = *t++)
;
}
I know i have done something(or many things) terribly wrong. Because whenever i try to run this code- it gives me segmentation fault. Like this-
Enter the first string
Hello
Enter the second string
Segmentation fault (core dumped)
It would be really helpful if someone points me out the flaw/flaws of my implementation. Thanks in advance.
Thank you very much guys, for such quick responses. But seems that wasn't the only problem. After writing the program like this-
#include<stdio.h>
void strcat(char *s, char *t);
int main()
{
char s1[20], s2[20];
printf("enter the first string\n");
scanf("%s",s1);
printf("Enter the second string\n");
scanf("%s",s2);
strcat(s1,s2);
printf("Strings concatenated\n");
printf("%s",s1);
return 0;
}
void strcat(char *s, char *t)
{
while(*s++)
;
while(*s++ = *t++)
;
}
It runs like this.
Enter the first string
Hello
Enter the second string
There
Hello
It only prints the first string i have entered. Now i think i have made some mistake on that strcat function too.
1) In the main(), you have to allocate memory for both s1 and s2 pointers
char *s1=malloc(100*sizeof(char)), *s2=malloc(100*sizeof(char));
scanf("%99s",s1); //the "%99s" allow to avoid buffer overflow
And if you use gcc and your gcc>2.7 then you can use "%ms" in the scanf() in this way:
scanf("%ms",&s1);
with the "%ms", the scanf() will allocate memory for s1 pointer
2) and you have to add s-- in
while(*s++)
;
s--; // add s-- here
while(*s++ = *t++)
;
because the s pointer is pointing in the next element of '\0' element. the s pointer should be pointed in the '\0' element before starting copy the second string
You don't allocate memory for s1, s1 (or initialized with array), Value of both s1, s1 are garbage .
char *s1, *s2;
printf("enter the first string\n");
scanf("%s",s1);
This causes an undefined behavior.
Suggestion use either:
#define SIZE 1024
char s1[SIZE], s2[SIZE];
or dynamically allocate memory using calloc()/maloc() functions:
char *s1, *s2;
s1 = malloc(SIZE);
s2 = malloc(SIZE);
and lately free() memory explicitly when work done with s1, s2.
Additionally instead of unsafe scanf() use fgets() function to avoid buffer overflow error. read Reading a line using scanf() not good?
I am a beginner in C. I wanted to make strcat function using pointers. I made it but don't know what is wrong with it. I used gcc compiler and it gave segmentation fault output.
#include<stdio.h>
#include<string.h>
char scat(char *,char *);
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
while(*q!='\0') printf("the concatenated string is %c",*q);
}
char *scat(char *s,char *t)
{
char *p=s;
while(*p!='\0'){
p++;
}
while(*t!='\0'){
*p=*t;
p++;
t++;
}
return p-s-t;
}
This one works:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *scat(char *,char *); /* 1: your prototype was wrong */
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
printf("cat: %s\n", q); /* 2: you can use %s to print a string */
free(q);
}
char *scat(char *s,char *t)
{
char *p=malloc(strlen(s)+strlen(t)+1); /* 3: you will have to reserve memory to hold the copy. */
int ptr =0, temp = 0; /* 4 initialise some helpers */
while(s[temp]!='\0'){ /* 5. use the temp to "walk" over string 1 */
p[ptr++] = s[temp++];
}
temp=0;
while(t[temp]!='\0'){ /* and string two */
p[ptr++]=t[temp++];
}
return p;
}
You have to allocate new space to copy at the end of s. Otherwise, your while loo[ will go in memory you don't have access to.
You shoul learn about malloc() here.
It is undefined behaviour to modify a string literal and s, and eventually p, is pointing to a string literal:
char* s = "james";
s is passed as first argument to scat() to which the local char* p is assigned and then:
*p=*t;
which on first invocation is attempting to overwite the null character an the end of the string literal "james".
A possible solution would be to use malloc() to allocate a buffer large enough to contain the concatentation of the two input strings:
char* result = malloc(strlen(s) + strlen(p) + 1); /* + 1 for null terminator. */
and copy them into it. The caller must remember to free() the returned char*.
You may find the list of frequently asked pointer questions useful.
Because p goes till the end of the string and then it starts advancing to illegal memory.
That is why you get segmentation fault.
It's because s points to "james\0", string literal & you cannot modify constant.
Change char *s="james"; to char s[50]="james";.
You need to understand the basics of pointers.
a char * is not a string or array of characters, it's the address of the beginning of the data.
you can't do a char * - char* !!
This is a good tutorial to start with
you will have to use malloc
You get a segmentation fault because you move the pointer to the end of s and then just start writing the data of p to the memory directly following s. What makes you believe there is writable memory available after s? Any attempt to write data to non-writable memory results in a segmentation fault and it looks like the memory following s is not writable (which is to expect, since "string constants" are usually stored in read-only memory).
Several things look out of order.
First keep in mind that when you want to return a pointer to something created within a function it needs to have been malloc'ed somewhere. Much easier if you pass the destination as an argument to the function. If you follow the former approach, don't forget to free() it when you're done with it.
Also, the function scat has to return a pointer in the declaration i.e. char *scat, not char scat.
Finally you don't need that loop to print the string, printf("%s", string); will take care of printing the string for you (provided it's terminated).
At first, your code will be in infinte loop because of the below line. you were supposed to use curely braces by including "p++; t++ " statements.
while(*t!='\0')
*p=*t;
though you do like this, you are trying to alter the content of the string literal. which will result in undefined behavior like segmentation fault.
A sequence of characters enclosed with in double quotes are called as string literal. it is also called as "string". String is fixed in size. once you created, you can't extend its size and alter the contents. Doing so will lead to undefined behavior.
To solve this problem , you need to allocate a new character array whose size is sum of the length of two strings passed. then append the two strings into the new array. finally return the address of the new array.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* scat(char *,char *);
void append(char *t , char *s);
int main(void)
{
char *s="james";
char *t="bond";
char *n = scat(s,t);
printf("the concatenated string is %s",n);
return 0;
}
char* scat(char *s,char *t)
{
int len = strlen(s) + strlen(t);
char *tmp = (char *)malloc(sizeof(char)* len);
append(tmp,s);
append(tmp,t);
return tmp;
}
void append(char *t , char *s)
{
//move pointer t to end of the string it points.
while(*t != '\0'){
t++;
}
while( *s != '\0' ){
*t = *s;
t++;
s++;
}
}