Strange thing about pointers - c

I have some misunderstanding about VS C++. In version 2010 the code below works fine: I can get a string and I can free memory afterwords.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAX 14
void GetString(char **str);
int main(int argc, char *argv[])
{
char *str = NULL;
GetString(&str);
printf("%s\n", str);
getchar();
free(str);
return 0;
}
void GetString(char **str)
{
char *s = (char *) malloc(sizeof(char) * MAX);
strcpy(s, "HELLO, WORLD!");
*str = s;
}
But in VS 2008 the code above will end up with memory corruption error. I guess, there is a small difference in standards used. Am I right? If no, could you, please, tell me, why the same code doesn't work in different versions of the Visual Studio?
Thank you beforehand for your answers.
p.s. I'm curious of what happens, but couldn't yet find any information on the topic.
p.p.s. Language used - C

You're not including the required headers, which means your code could be interpreted differently by different compilers. You should add:
#include <stdlib.h>
to make malloc() a well-defined function.
You're also calling strcpy(), so you need:
#include <string.h>
and doing I/O, for which you need:
#include <stdio.h>
Also, in C this:
char *s = (char *) malloc(sizeof(char) * MAX);
is better written as:
char *s = malloc(MAX);
since
It's a bad idea to cast the return value of malloc()
sizeof (char) is always 1, so it just adds clutter.
Finally, you should of course check that malloc() succeeds before using the returned pointer.

Related

strcpy in C is illegally altering the copied string?

This is a really mysterious behavior I can't get around.
I'm trying to edit the string of one variable and then copy again to the source. I have the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char word[100] = "1 hash";
char* sp = malloc(100);
sp = strchr(word, ' ');
sp++;
// the "bug" still happens with strcpy instead of strncpy
strncpy(word, sp, 100);
printf("%s\n", word);
}
The output is:
hhsh
It should've been hash.
The weird thing is that "1 hash" is the only string I found that this bug happens. All the other strings I tried gave me the expected output. For example: "1 huhanh" -> huhanh or "3 a h c" -> a h c
Any help would be greatly appreciated.
You have undefined behavior. The malloc pointer is ignored.
So, when you do the strcpy, sp and word are part of the same string.
This is UB. Which means it may segfault. It may work. It may produce incorrect results.
In this instance, we can't predict the order of the fetching of the bytes and the storing. With certain sequences, it will [appear to] work. With others, we may fetch a byte that was not an input but an output from the previous byte.
Here is the corrected code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main()
{
char word[100] = "1 hash";
char *copy = malloc(100);
char *sp = strchr(word, ' ');
sp++;
strncpy(copy, sp, 100);
printf("%s\n", copy);
}
UPDATE:
Thanks for the answer. I indeed didn't realized they were all part of the same string. In the example code u provided, does the pointer sp still have to exist? –
Pedro Vinícius
Yes, because it is where you are copying from. Notice that you get the pointer from strchr. Then, you increment it. It is this updated value that becomes the source address.
This is clean code.
But, you could do:
strncpy(copy, strchr(word, ' ') + 1, 100);
But, I wouldn't do this. IMO, it's "too cute". The original sp code will execute just as fast. And, it's easier to read. And it let's you do some error checking:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main()
{
char word[100] = "1 hash";
char *copy = malloc(100);
char *sp = strchr(word, ' ');
if (sp != NULL) {
sp++;
strncpy(copy, sp, 100);
}
else
*copy = 0;
printf("%s\n", copy);
}
char* sp = malloc(100);
The problem is that this allocated memory is not used, at all. strchr returns a pointer to a character in the original string. And according to the documentation
destination and source shall not overlap
this code
char* sp = malloc(100);
sp = strchr(word, ' ');
allocates some memory then leaks it away. sp ends up pointed into the 'word' on the stack

Change string value by address C

I'm trying to change the value of a string by passing its address to a function.
I get NULL as a result.I tried strcpy but it dosen't work for pointers on strings.
Code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void changeStr (char ** tmpP){
char* test="Hello world !";
char** add=&test;
tmpP=add;
}
int main() {
char* tmp;
changeStr(&tmp);
printf("\n %s \n",tmp);
return 0;
}
result :
(NULL)
Currently the behaviour of your code is undefined as changeStr is a no-op, and you are attempting to call printf with the uninitialised variable tmp. That accounts for your (arbitrary) output. On other occasions the compiler might eat your cat.
add has automatic storage duration, and tmpP is the result of a value copy of &tmp from the caller. These assignments, although perfectly valid, are not visible to the calling function main().
The solution is to write
*tmpP = "Hello World";
as the only statement in changeStr.
You should note that tmp in main() will point to a read-only string literal.
What your doing is the mistake, tmpP=add; you thought that the add value will point to tmpP.
If you want to change the value of string passed to function, you can do in this way. I saw already #Bathseba pointed out.
Try this,
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void changeStr (char ** tmpP){
char* test;
char** add=&test;
*tmpP= "Hello world !";
}
int main() {
/* Here it has string cruel that pass to function*/
char* tmp="Cruel";
changeStr(&tmp);
printf("\n %s \n",tmp);
return 0;
}
Output:
Hello world !
What you did.
void changeStr (char ** tmpP){
char* test = "Hello world !";
char** add=&test;
tmpP=add; //<-- Here your assigning add to tmpP, it shouldn't.
}

How to compose characters into a single string in memory?

I am working on a school assignment and I need a little bit of help.
My question is, how can I compose characters that are read in from a file into a single string of memory. Here is what i have so far.
My Code:
#include <stdio.h>
#include <stdlib.h>
char myString;
int main(int argc, char *argv[]){
FILE* fin;
char ch;
fin=fopen(argv[1],"r");
while((ch=fgetc(fin))!=EOF){
printf("%c\n", ch);
}
fclose(fin);
return 0;
}
My teacher said the last part of main is to be:
putchar(‘\n’);
printf( myString );
return 0;
}
But I'm not sure how to put that within my code. Thank you ahead of time, Im also not looking to be just given the answer if you could help me work it out that would be great thank you again.
Updated code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
FILE* fin;
int i;
char myString[3];
fin=fopen(argv[1],"r");
while(fgets(myString,sizeof(myString), fin)){
putchar('\n');
printf("%c\n", myString[i]);
}
fclose(fin);
return 0;
}
Im unsure if this code is exactly correct. It prints out the items within the file and puts a space between them. and there is an array being used for the string.
Im also not looking to be just given the answer
Fine.
Define a char array (mystring) large enough to hold your string
Define a counter to keep track of the position in the array
At each step store ch into the array
Remember to 0-terminate it (store 0 as the last element).
Things to note:
You will need to learn about realloc and grow the storage as you go if your program is to read arbitrarily long input. Better leave that for later
It's generally unsafe to printf(dynamicstr). What if it contains a "%d" ? It's better to printf("%s", dynamicstr).
You get to learn about memcpy and malloc. They are your friends.
--Jason
You need to read the applicable part of your textbook that explains what a "string" is in C. Without you understanding that, there's almost no way to answer your question without simply doing it for you.
A C "string" is a contiguous chunk of memory containing chars and is NULL terminated. You'll need to allocate that then place the characters into it as you read them from the file. Note that you have to make sure you don't go beyond the memory you've allocated while doing so, this is called a "buffer overflow".
#include <stdio.h>
#include <stdlib.h>
char* myString;
int main(int argc, char *argv[]){
FILE* fin;
fpos_t fsize = 0;
char ch;
char *pch;
fin=fopen(argv[1],"r");
fseek(fin,0,SEEK_END);
fgetpos(fin, &fsize);
rewind(fin);
pch = myString = (char*)malloc((fsize+1)*sizeof(char));
while((ch=fgetc(fin))!=EOF){
*pch++ = (char)ch;
}
*pch = '\0';
fclose(fin);
printf("%s", myString);//printf(myString);// need escape %
free(myString);
return 0;
}

how to assign a value to a string array?

for example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char substr[10][20];
int main() {
substr[0] = "abc";
printf("%d", substr[0]);
}
of course above is wrong? how to do it? thanks
You can't assign strings like that in C. Instead, use strcpy(substr[0], "abc"). Also, use %s not %d in your printf
I hate giving 'full' answers to homework questions, but the only way to answer your question is to show you the answer to your problem, because it is so basic:
#include <stdio.h>
#include <string.h>
#define MAXLEN 20
char substr[10][MAXLEN];
int main(void) {
strncpy(substr[0], "abc", MAXLEN);
puts(substr[0]);
return 0;
}
Your code (as is) has several faults:
You are treating substr[0] as a string literal. You can't do that.
You were using printf formatters incorrectly. %s is for strings
You don't need to bother printf() to print a string
You should (in real code) watch out for buffer overflows, hence strncpy()
If main() doesn't want / need argc and argv, its arguments should be void
main() should return a value, as its return type is int
You aren't using anything out of <stdlib.h>, why include it?
I suggest researching string literals, the functions available in <string.h> as well as format specifiers.
Also note, I am not checking the return of strncpy(), which is something you should be doing. That is left as an exercise for the reader.
Hope this helps:
void main(void)
{
char* string[10];
string[0] = "Hello";
}
Otherwise I think ya need to copy it by hand or use strcpy or the like to move it from one block of memory to another.

simple string runtime error in C?

This code compiles fine but give segmentation fault error while running? Can anyone tell why?
#include <stdio.h>
#include <string.h>
#include <math.h>
int main() {
const char s2[] = "asdfasdf";
char* s1;
strcpy(s1, s2);
printf("%s", s1);
return 0;
}
You allocated space for a single pointer, s1, but not the bytes pointed at by s1.
A solution is to dynamically allocate memory for s1:
s1 = (char *)malloc(strlen(s2) + 1);
strcpy(s1, s2);
Keep in mind that you need to allocate one more byte of memory (the +1 in the call to malloc) than the number of characters in s2 because there is an implicit NULL byte at the end.
See C Memory Management (Stack Overflow) for more information.
You didn't allocate memory for s1. You have a pointer to s1 but no memory allocated for the strcpy to copy the value of s2 into.
char *s1 = malloc( strlen(s2) + 1 );
strcpy( s1, s2 );
You have not allocated any memory to s1. It is a pointer to nothing.
char* s1 = malloc(sizeof(s2));
strcpy(s1, s2);
printf("%s", s1);
free(s1);
The problem is that s1 does not have any memory associated with it. strcpy does not call malloc().
You could either do:
char s1[10];
or
char *s1 = malloc(10);
What they all said, you need to allocate the space for s1. What everyone else has posted will work just fine, however, if you want a simpler way to allocate space for an existing string and copy it into a new pointer then use strdup like this:
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
int main() {
const char s2[] = "asdfasdf";
char* s1;
s1 = strdup(s2);
printf("%s", s1);
return 0;
}
Someone mentioned strdup earlier, that would be a way to use it. Most systems should support it since it is in the standard C libaries. But apparently some don't. So if it returns an error either write your own using the method already mentioned, or just use the method already mentioned ;)
No one yet has pointed out the potential of strdup (String Duplicate) to address this problem.
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
int main() {
const char s2[] = "asdfasdf";
char* s1;
s1 = strdup(s2); // Allocates memory, must be freed later.
printf("%s", s1);
free(s1); // Allocated in strdup, 2 lines above
return 0;
}
You need to allocate the destination (and using namespace std; isn't C but C++, the rest of the code is C).
You have to allocate memory to the pointer s1. If you don't do that, it will be pointing somewhere unknown, and thus arriving at the segmentation fault. The correct code should be:
#include <stdio.h>
#include <string.h>
#include <math.h>
int main() {
const char s2[] = "asdfasdf";
char* s1 = malloc(21 * sizeof(s2[0]));
strcpy(s1,s2);
printf("%s",s1);
return 0;
}

Resources