I am having trouble generating a string inside a C routine.
Goal
Have function generate a custom string and return the value
e.g. 'void getName( char ** name )'
Attempt
int main(void) {
char *name;
getName(&name);
}
void getName(char **name) {
*name = "#"; // Load with prefix
//?strcpy(*name[1], "123"); // Goal: "#123"
}
How can I have getName() generate #123 as shown here?
1st problem: use malloc to allocate memory.
char *name = malloc(sizeof("#123")+1);
Even if you will run it after allocating memory, it will give runtime error; as you are doing:
*name = "#";
The problem is first you allocate space for 5 chars and point your pointer to the beginning of that memory. Then in the second line you point your pointer to a string literal causing a memory leak.
The pointer no longer points to the allocated memory.
You will like to do this:
int main(void) {
char *name = malloc(sizeof("#123")+1);
getName(&name);
printf("%s", name);
free(name);
name = NULL;
}
void getName(char **name) {
strcpy((*name), "#");
strcat(*name,"123");
}
Related
i ma new c and i am trying sprintf along with pointers. all i get in console is return buf; as is please help me with this code.
#include <stdio.h>
char* stringa(char* str);
int main()
{
char* ss = "123";
stringa(ss);
return 0;
}
char* stringa( char* str)
{
char buf [100] ;
sprintf(buf,"hello %s", str);
return buf;
}
i tried many other ways too like sprintf_c and my computer shut down for serious. i am learning c.
Maybe this is what you want
#include <stdio.h>
char* stringa(char* dest, char* src)
int main()
{
char buf [100] ;
char* ss = "123";
printf("%s\n", stringa(buf, ss));
return 0;
}
char* stringa(char* dest, char* src)
{
sprintf(dest,"hello %s", src);
return dest;
}
In function 'char* stringa(char* str)' you are not allocating space in the heep for the char array 'buf' you are allocating space on the stack for that variable. (meaning after the function finishes, the variable 'buf' will be wiped away because it will be out of scope) therefore you must ask the compiler to allocate space in memory for this array, I recommend using malloc()
ex:
char* stringa( char* str)
{
char *buf = (char*)malloc(sizeof(char) * 100);
sprintf(buf,"hello %s", str);
return buf;
}
char* stringa( char* str)
{
char buf [100] ;
sprintf(buf,"hello %s", str);
return buf;
}
The problem with this code is that the buf char array is local to the stringa function. When the function returns, the memory occupied by the buf array is not valid anymore (for example, it could be reused later to store the content of other variables, arrays, etc.).
So when the function returns, you are giving the caller a pointer to garbage memory, to invalid data. The C compiler is trying to help you with that warning message; it's telling you: "Sorry, you are trying to pass back to the caller the address of a local variable (i.e. the buf char array) that is not valid anymore when the function terminates."
To fix this problem one option could be to allocate the char array for the output string at the call site, and let the invoked stringa function write into the caller-provided array:
#include <stdio.h>
char* stringa(char* dest, const char* str);
int main()
{
const char* ss = "123";
char buf[100];
stringa(buf, ss);
return 0;
}
/* Write the final message into 'dest'.
* Return the same dest address.
*/
char* stringa(char* dest, const char* str)
{
/* Note: better using a safe string function
* to prevent buffer overflows (e.g. sprintf_s),
* passing the maximum destination array size as well.
*/
sprintf(dest,"hello %s", str);
return dest;
}
Note that I also added some consts in your code to enforce some const-correctness for read-only input strings.
in my code I have a function that can initialize new instance of a struct, which has a char attribute, and the same function returns a pointer to an instance.
But when I try to read the char attribute from different scopes, I get also different characters.
Below you can find my code and also the results.
Thanks in advance!
Main function
Here the character is printed correctly.
int main(int argc, char const *argv[]) {
char line[] = "2-11 f: fjdfffmffffrff";
char *pnt = line;
Entry *entry = getEntry(&pnt);
printf("(main) min %d\n", entry->min);
printf("(main) max %d\n", entry->max);
printf("(main) character %c\n", entry->character); <-----
printf("(main) password %s\n", entry->password);
printEntry(entry);
return 0;
}
Function
While here the printed character is some random char.
void printEntry(Entry * entry){
printf("(function) min %d\n", entry->min);
printf("(function) max %d\n", entry->max);
printf("(function) character %c\n", entry->character); <--
printf("(function) password %s\n", entry->password);
}
STDOUT
Here are the results.
(main) min 2
(main) max 11
(main) character f
(main) password fjdfffmffffrff
(function) min 2
(function) max 11
(function) character L
(function) password fjdfffmffffrff
Edit
Entry struct
typedef struct Entry {
int min, max;
char character;
char *password;
} Entry;
char **separateBySpace(char **stringPtr) {
char **ptrArray = (char **) malloc(ARR_PTR_LEN * sizeof(char *));
char delim[] = " ";
char *ptr = strtok(*stringPtr, delim);
ptrArray[0] = ptr;
int x = 1;
while (ptr != NULL) {
if (x >= ARR_PTR_LEN) {
break;
}
ptr = strtok(NULL, delim);
ptrArray[x] = ptr;
x++;
}
return ptrArray;
}
Entry *getEntry(char **stringPtr) {
char **pntArray = separateBySpace(stringPtr);
char *rules = pntArray[0];
char *character = pntArray[1];
char *password = pntArray[2];
int *array = getRange(rules);
Entry entry = {.min = *(array), .max= *(array + 1), .character = *(character), .password= password};
Entry *pntEntry = malloc(sizeof(struct Entry));
pntEntry = &entry;
return pntEntry;
}
Function getEntry returns the address of a non-static local variable. Using this address in main is undefined behavior. Probably the call to printEntry partially overwrites the data, that's why you see different output.
You try to dynamically allocate memory for the returned data with
Entry *pntEntry = malloc(sizeof(struct Entry));
but you throw away the address to this memory and assign the address of your local variable with
pntEntry = &entry;
You probably want to copy the structure instead of the pointer. This would be
*pntEntry = entry;
Not related to your problem:
Your program should free all allocated memory when it is no longer used.
With the code shown in the question it is not necessary to pass the address of the pointer to the input string to getEntry and separateBySpace as a type char** because you don't want to modify the pointer. Passing a char* would be sufficient.
In separateBySpace you return an array of pointers that point to characters of the input string which gets modified by strtok. Later in getEntry you assign the pointer password to a pointer in your Entry structure. This means you should not change the string variable that was passed as an argument to getEntry, otherwise the password´ string referenced in the returned Entry` structure will change.
Edit (to answer a comment):
I think in getEntry you can free the pointer array allocated in separateBySpace because all values have been used or copied to the Entry structure.
At the end of the program you should free the memory pointed to by entry that was allocated in getEntry.
You must not free the memory password because this points to a character in your local variable line. Freeing entry->password before freeing entry would be necessary if you would allocate memory for a copy of the password, for example using strdup. This would also fix the possible problem that entry->password points to an element of line.
I need to write a program in which is structure with two fields: integer and string. Next I need to write a function which dynamically allocates this structure and takes int and string as parameters to pass them down to allocated structure. This function will also return pointer to newly made structure. Second element of this program should be function which takes struct pointer as parameter, then prints all of the fileds on screen and then free memory of struct. This is the best I could come up with.
#include <stdio.h>
#include <stdlib.h>
struct str{
int num;
char text[20];
};
struct str* return_address(int *num, char *text){
struct str* new_struct=malloc(sizeof(struct str));
new_struct->num=num;
new_struct->text[20]=text;
return new_struct;
};
void release(struct str* s_pointer){
printf("%d %s", s_pointer->num, s_pointer->text);
free(s_pointer);
};
int main()
{
struct str* variable=return_address(1234, "sample text");
release(variable);
return 0;
}
Your array is very small, also it's not dynamic at all. If you are allocating using malloc() anyway, why not allocate everything dynamically?
You cannot assign to an array.
The num member, which I suppose is meant to store the length of the "string", is being assigned a pointer, which is not what you apparently want. And also, the behavior is only defined in very special circumstances when you assign a pointer to an integer, the compiler should be warning you unless you turned off warnings.
Perhaps you want this,
struct string {
char *data;
int length;
};
struct string *
allocate_string(int length, const char *const source)
{
struct string *string;
string = malloc(sizeof *string);
if (string == NULL)
return NULL;
string->length = strlen(source);
// Make an internal copy of the original
// input string
string->data = malloc(string->length + 1);
if (string->data == NULL) {
free(string);
return NULL;
}
// Finally copy the data
memcpy(string->data, source, string->length + 1);
return string;
}
void
free_string(struct string *string)
{
if (string == NULL)
return;
free(string->data);
free(string);
}
I have a malloced string that I needed to parse. I did all of the parsing using strtok(). Strtok has returned a pointer to me and if I printf using that pointer the correct part of the parsed string gets printed. Afterwards I will be freeing the malloced string that the pointer returned by strtok was pointing too.
How do I store what the pointer was pointing at into a struct such that the value remains in the struct variable even after the main string has been freed.
String: Tommy-1234567
My strtok return pointer:
char *studentName= strtok(String1,"-");
char *studentNo= strtok(NULL,"-");
My struct:
typedef struct Student{
char *name; //Want name to be stored here even after string is freed
int *studentNumber; //Want no. to be stored here even after string is freed
}Student;
In this example about the use of strdup, the program makes copies of the data obtained from strtok. The original string can then be freeed
The code posted has a mistake trying to assign a char* pointer to int*. In C, a textual number is not automatically converted to int.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Student{
char *name;
int studentNumber;
} Student;
int main(void)
{
char *string;
char *tok;
Student acolyte;
// set up the input, like this to show use of `strdup` and `free`
string = strdup("Tommy-1234567"); // allocate memory for source string
if (string == NULL) // check it worked
return 1; // failure
// student name
tok = strtok(string, "-"); // isolate first token
if (tok == NULL) // check it worked
return 1; // failure
acolyte.name = strdup(tok); // allocated mem for substring and copy
if (acolyte.name == NULL) // check it worked
return 1; // failure
// student number
tok = strtok(NULL, "-"); // isolate next token
if (tok == NULL) // check it worked
return 1; // failure
if (sscanf(tok, "%d", &acolyte.studentNumber) != 1) // extract int
return 1; // failure
free(string); // can now get rid of source data
// show result
printf("Name: %s\n", acolyte.name);
printf("Number: %d\n", acolyte.studentNumber);
free(acolyte.name); // free the memory in struct
return 0;
}
Program output:
Name: Tommy
Number: 1234567
Allocate More Memory
Since you are freeing the string that you parsed, see man(3) strdup
char *newstring = strdup(oldstring);
I call a function global var as follow:
char *Pointer;
I then pass it into function:
char *MyChar = DoSomething (&Pointer);
which is defined as:
char *DoSomething (char *Destination)
{
free (*Destination);
//re-allocate memory
Destination = malloc (some number);
//then do something...
//finally
return Destination;
}
it only works if I use (*Destination) instead of (Destination). can someone tell me if that is correct? I still do not understand why it does not take (Destination).
It is correct, Destination is already declared as a pointer, so you pass the address of Destination in DoSomething(&Destination), that is like a pointer to pointer, then you need to dereference Destination inside DoSomething() function, for which the indirection operator * works.
But the right way, is not to pass the address of the pointer, but the pointer instead like in
DoSomething(Destination);
now, since you want to malloc Destination inside the function, you should the do this
char * DoSomething( char **Destination )
{
// free( Destination ); why?
//re-allocate memory
*Destination = malloc( some number );
//then do something...
//finally
return *Destination;
}
this is a demonstration of how you can use pointers
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *copyString(const char *const source)
{
char *result;
int length;
length = strlen(source);
result = malloc(length + 1);
if (result == NULL)
return NULL;
strcpy(result, source);
printf("The address of result is : %p\n", result);
printf("The content of result is : %s\n", result);
printf("The first character of result is # %p\n", &result[0]);
return result;
}
int main()
{
char *string = copyString("This is an example");
printf("\n");
printf("The address of string is : %p\n", string);
printf("The content of string is : %s\n", string);
printf("The first character of string is # %p\n", &string[0]);
/* we used string for the previous demonstration, now we can free it */
free(string);
return 0;
}
if you execute the previous program, you will see that the pointers both point to the same memory, and the contents of the memory are the same, so calling free in main() will realease the memory.
Here is a correct approach
char *Pointer;
//,,, maybe allocating memory and assigning its address to Pointer
//... though it is not necessary because it is a global variable and
//... will be initialized by zero. So you may apply function free to the pointer.
char *MyChar = DoSomething( Pointer );
char * DoSomething( char *Destination )
{
free( Destination );
//re-allocate memory
Destination = malloc( some number );
//then do something...
//finally
return Destination;
}
As for your code then
Type of the argument does not correspond to type of the parameter in function call
char *MyChar = DoSomething (&Pointer);
the type of the parameter is char * ( char *Destination ) while the type of argument is
char ** ( &Pointer )
As Destination is a pointer then instead of
free (*Destination);
you have to write
free( Destination );
It's because you are passing in an address of the pointer char *Pointer with the line
char *MyChar = DoSomething (&Pointer);
Since you are passing in the address of the pointer in your function DoSomething it sees the functional scope variable Destination as a pointer to an address that is the address of the pointer Pointer.
So rather than passing in the address of Pointer with
char *MyChar = DoSomething(&Pointer);
you need to pass in the pointer itself like so:
char *MyChar = DoSomething(Pointer);
which will allow you to use
free(Destination);
Notice the lack of & indicating the address of Pointer.