strlen code not working - c

Working on this little piece of code, but for some reason it keep crashing the whole time.
Anyone got an idea what i'm doing wrong
char *str;
printf("Enter a string\n");
gets(str);
printf("The size of the string is %d", strlen(str));
system("PAUSE");
return 0;

You have not allocated any memory for str. Declare a buffer, for example char str[50], but be aware of buffer overflows.

You only created an char* pointer which points to random space in memory and you try to do something with it - and that is why your program crashes.
You should create an array of chars:
char str[50];
or dynamically allocate memory for string with malloc:
char* str;
str = (char *)malloc(50*sizeof(char)); // allocate memory
// some operations
free(str); // deallocate memory
where 50 is your estimated size of buffer.

Related

How to use fscanf() for two strings (of ANY length) and dynamically allocate/de-allocate the memory properly

I need to read an input .txt file and print out two separate strings from each line in the file. I used a while loop and a fscanf function to get each string and ignore blank space between. If the strings in a line of the input file are too long, I get a segmentation fault. However, I am also getting a munmap_chunk(): invalid pointer error when I run my executable.
If I don't allocate memory for string1 and string2, fscanf doesn't work properly. I believe fscanf is changing the pointers to string1 and string2, which is causing the munmap_chunk() error. However, I need to de-allocate the memory I gave string1 and string2 so I don't have memory leaks.
How do I scan this file for strings (of ANY length) and de-allocate the memory properly?
int main(int argc, char *argv[])
{
char *string1;
char *string2;
string1 = (char *)malloc(sizeof(string1)); //these strings need memory allocated for the fscanf to function properly
string2 = (char *)malloc(sizeof(string2));
FILE* file = fopen(argv[1], "r");
while (fscanf(file, "%s %s", string1, string2) != EOF)
{
printf("%s %s\n", string1, string2);
}
fclose(file);
//Deallocating memory
free(string1);
free(string2);
return 0;
}
'fscanf' does not change pointers but it can corrupt memory if you do not allocate enough space for your input.
And you are not allocating the memory correctly: string1 and string2 are pointers, so all you are allocating is a size of a pointer (4 or 8 bytes depending on your system).
If you need to read a line from a file and you do not know the maximum length of the line in advance, you can not use fscanf.
You need to allocate a starting buffer, say something like:
string1 = malloc(512 * sizeof(char));
Were 512 is an arbitrary but reasonably large length for a line.
You then use fread to read one byte at a time in a loop, and check for end of line (usually '\n').
You must also count how much you read, and if the line is longer than 512 bytes, use realloc to increase the size of your buffer, like so:
if (bytesRead == (string1Size - 1) && curByte != '\n') {
string1Size += 512;
string1 = realloc(string1, string1Size);
}
Here, bytesRead is an int variable counting how many bytes you successfully read so far, and string1Size is also int variable used to track the size of string1 buffer.
string1 = (char *)malloc(sizeof(string1)); allocates memory for just 4 or 8 characters because string1 is a char * and that's how big a pointer is.
To allocate memory for let's say 100 characters you need to do char *string1 = malloc(sizeof(char) * 100).
How do I scan this file for strings (of ANY length) and de-allocate the memory properly?
You can't with fscanf because it mixes reading input with parsing input. You don't know what's going to be read before you parse it.
Instead, read the line into a large buffer where you can examine it. Once you know how big the pieces are you can allocate just the right amount of memory and copy to it.
Because we are reusing the line buffer, and throwing it away when we're done, we can make it as large as we think we'll ever need. 1024 or 4096 are often good choices. I like BUFSIZ.
char line[BUFSIZ];
while( fgets(line, sizeof(line), file) ) {
// now parse line
}
The parsing can be done in various ways. A simple one is strtok (STRing TOKenize). This tokenizes line in place. Copy them to the right amount of memory with strdup.
char line[BUFSIZ];
while( fgets(line, sizeof(line), file) ) {
char words[2];
int i = 0;
for(
char *word = strtok(line, " ");
word;
word = strtok(NULL, " ")
) {
words[i] = strdup(word);
i++;
}
printf("%s %s", words[0], words[1]);
free(words[0]);
free(words[1]);
}
line and words are allocated on the stack, they will be freed automatically. But the memory allocated by strdup is on the heap, it needs to be freed.

Taking string input in char pointer

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char *s;
printf("enter the string : ");
scanf("%s", s);
printf("you entered %s\n", s);
return 0;
}
When I provide small inputs of length up to 17 characters (for example "aaaaaaaaaaaaaaaaa") the program works perfectly fine but on providing inputs of larger lengths, it gives me a runtime error saying "main.c has stopped working unexpectedly".
Is there some problem with my compiler (codeblocks) or my pc (windows 7)? Or is it somehow related to the input buffer of C?
It's undefined behaviour as the pointer is uninitialized. There's no problem with your compiler but your code has problem :)
Make s point to valid memory before storing data in there.
To manage buffer overflow, you can specify the length in the format specifier:
scanf("%255s", s); // If s holds a memory of 256 bytes
// '255' should be modified as per the memory allocated.
GNU C supports an non-standard extension with which you don't have to allocate memory as allocation is done if %as is specified but a pointer to pointer should be passed:
#include<stdio.h>
#include<stdlib.h>
int main() {
char *s,*p;
s = malloc(256);
scanf("%255s", s); // Don't read more than 255 chars
printf("%s", s);
// No need to malloc `p` here
scanf("%as", &p); // GNU C library supports this type of allocate and store.
printf("%s", p);
free(s);
free(p);
return 0;
}
the char pointer is not initialized, you should dynamiclly allocate memory to it,
char *s = malloc(sizeof(char) * N);
where N is the maximum string size you can read, And its not safe to use scanf
without specifying the maximum length for the input string, use it like this,
scanf("%Ns",s);
where N same as that for malloc.
You are not allocating any memory to the character array so first try to get memory by calling malloc() or calloc(). then try to use it.
s = malloc(sizeof(char) * YOUR_ARRAY_SIZE);
...do your work...
free(s);
You need to allocate enough memory for buffer where your pointer will point to:
s = malloc(sizeof(char) * BUF_LEN);
and then free this memory if you do not need it anymore:
free(s);
You're not allocating memory for your string, and thus, you're trying to write in a non-authorized memory address. Here
char *s;
You're just declaring a pointer. You're not specifying how much memory to reserve for your string. You can statically declare this like:
char s[100];
which will reserve 100 characters. If you go beyond 100, it will still crash as you mentionned for the same reason again.
The problem is with your code .. you never allocate memory for the char *. Since, there is no memory allocated(with malloc()) big enough to hold the string, this becomes an undefined behavior..
You must allocate memory for s and then use scanf()(I prefer fgets())
#include"stdio.h"
#include"malloc.h"
int main(){
char *str;
str=(char*)malloc(sizeof(char)*30);
printf("\nENTER THE STRING : ");
fgets(str,30,stdin);
printf("\nSTRING IS : %s",str);
return 0;
}
The code in C to read a character pointer
#include<stdio.h>
#include<stdlib.h>
void main()
{
char* str1;//a character pointer is created
str1 = (char*)malloc(sizeof(char)*100);//allocating memory to pointer
scanf("%[^\n]s",str1);//hence the memory is allocated now we can store the characters in allocated memory space
printf("%s",str1);
free(str1);//free the memory allocated to the pointer
}
I was getting this problem. I tried this code below and it worked:
char *text;
scanf("%s", *&text);
I dont know how it worked. I just felt like doing it.

convert morse code to english in c

I have already done some code but it does not run correctly
what I have done so far
void keyread1(void)
{
char *string1= (char*) malloc (20);//char pointer pointing to allocated memory
char *string2= (char*) malloc (20);
char *string3= (char*) malloc (20);
char *string4= (char*) malloc (20);
string4[0]='\0';
printf("Enter word to convert to morse code: \n");
scanf("%s", string1);
while (string1!='\0')
{
int z=0,a=0;
strncpy(string2+a, string1+z,4 );
string3=morse2english(string2);
strncat(string4+a,string3,1);
z=z+4;
}
printf("morse code string: %s\n",string4);
free(string1);
return;
}
char *morse2english(char *morsecode)
{
int j=0;
int a=0;
char *azarray=(char*)malloc(26);
strcpy(azarray, "abcdefghijklmnopqrstuvwxyz");
char *morsearray=(char*)malloc(104*sizeof(char));
strcpy(morsearray, ".- -...-.-.-.. . ..-.--. ...... .----.- .-..-- -. --- .--.--.-.-. ... - ..- ...-.-- -..--.----..");
for (int i = 0; i < 104; ++i )
for(int j=0;j<4;j++)
if((morsecode[j++] == morsearray[i++]))
a =((morsearray[i-4])/4);
char *ch =(char*)malloc(1*sizeof(char));
ch=azarray+a;
return ch;
}
the function keyread is supposed to split the morse string into 4 chars
and pass that to the morse2english function which is supposed to find the alphabetical representation of the morse code
and return it to the keyread function and add it to string4
I was putting the problems in a comment, but there are just too many! You really need to go back and study some more - especially about dynamic memory allocation!
in keyread1:
All the strcpy stuff with malloced buffers is not necessary. eg: you malloc 20 bytes for string3 but before you use it you say string3=..., so it's an instant leak!
while(string1 != '\0') is not comparing apples to apples: string 1 is a pointer, \0 is a character. You probable mean *string1, but then you never modify string1, so the loop wont end.
You never modify a in the loop, so you aren't appending to the string4
The result of morse2english is dynamically allocated but you never free it.
in morse2english:
you malloc an array of 26, (which doesn't allow a null terminator so you have a buffer overrun)
you never free azarray - why malloc in the first place, you don't modify it, so a string literal would work.
Ditto for morsearray (I didn't count it, but you don't change it, so no need to malloc and strcpy)
The for loop appears to be gibberish: for each individual char in all the morse code, look at the input (and modify the indexes used by the for loops)

Can't declare two character pointers [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
why does c allow initialization of string without declaration?
I am trying this rather simple code:
#include<stdio.h>
void copy(char *,char *);
main() {
char *name;
char *surname;
printf("Enter name: ");
scanf("%s",name);
printf("%s",name);
}
But for some reason, after I enter a name and press Enter, the program hangs and gives a message like Program has stopped working. However when I remove the 2nd character pointer declaration, that is the char *surname;, it works just as expected. What is the problem here?
You have not allocated memory for the pointers, so the scanf accesses arbitrary unspecified memory, which is undefined behaviour.
You need to pass pointers to sufficiently large memory blocks to scanf, either declare
char s1[100], s2[100];
(if 100 is large enough), or malloc memory
char *s1 = malloc(100);
char *s2 = malloc(100);
if (!s1 || !s2) {
// malloc failure
exit(EXIT_FAILURE);
}
You are writting into unallocated memory. That is undefined behavior,
You can do 2 things here:
declare your arrays of chars as having a fixed size at compile-time like this: char name[100]; (which means you can't change their size at runtime)
allocate room for char *name using malloc() or calloc() functions in stdlib.h
In any case you absolutely have to make sure you only allow the user to input the amount of bytes you allocated, otherwise bad things can and will happen!
A small study on what an evil person can (and will ;) do if you fail to define said boundaries can be found here: http://www.cultdeadcow.com/cDc_files/cDc-351/
Because you didn't allocate memory for it, and the string you put in it screws the code of the program. Try to use sscanf and getline:
#include <stdio.h>
int main()
{
int nbytes = 100;
char *my_string;
int int1, int2, int3;
int args_assigned;
args_assigned = 0;
while (args_assigned != 3)
{
puts ("Please enter three integers separated by whitespace.");
my_string = (char *) malloc (nbytes + 1);
getline (&my_string, &nbytes, stdin);
args_assigned = sscanf (my_string, "%d %d %d", &int1, &int2, &int3);
if (args_assigned != 3)
puts ("\nInput invalid!");
}
printf ("\nThanks!\n%d\n%d\n%d\n", int1, int2, int3);
return 0;
}
check out this:
Reading in a variable length string user input in C
and this :
http://en.wikipedia.org/wiki/Buffer_overflow
You declare a pointer and do not give it a valid memory address, it points to a random addrss. You cannot read or write with this pointer. Pointers should be used like this:
char s1[100],s2[100];
char * name=s1;
char * surname=s2;

Memory Clobbered

I am puzzled by this response.Can anyone help me on this and point out where I am making a mistake? The output at codepad is "memory clobbered before allocated block"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *s = (char *)malloc(10 * sizeof(char));
s = "heel";
printf("%s\n",s);
printf("%c\n",s[2]);
printf("%p\n",s);
printf("%d\n",s);
free(s);
return 0;
}
You're trying to free constant memory with:
free(s); // cannot free constant "heel"
What you're doing is allocating a piece of memory and storing its location (char *s). You are then overwriting that reference with one to a string constant "heel" (memory leak), which cannot be freed. To make this behave as desired, you should be copying the constant string to the memory you allocated:
strcpy(s, "heel");
Here is an example for getting user input:
char *input = malloc(sizeof(char) * 16); // enough space for 15 characters + '\0'
fgets(input, 16, stdin);
// do something with input
free(input);
To expand on #TimCooper's answer:
first you do: char *s = (char *)malloc(10 * sizeof(char));
then: s = "heel";
The first line allocates memory and assigns the location of that memory to s. But the second line reassigns s to the memory location of constant string heel on the stack!
Which means you try and free() memory on the stack, which is illegal. AND you leak memory, since what you first allocated to s is now inaccessible.
If you want to write a string into the memory pointed by s, you should use something like strcpy() (or, better, strncpy()).
You cannot free(s) - it's constant memory.
Try to change s = "heel"; with strcpy(s,"heel");
char *s = (char *)malloc(10 * sizeof(char));
s = "heel";
Doesn't do what you think, or what you would expect with more modern languages
The first line allocates some memory for 10chars and returns the address of it.
The second line changes that address to point to a constant block of memory allocated at compile time, containing "heel" losing the link to the allocated memory - leaking it

Resources