Valgrind C: How to input string from stdio - c

This is code:
char* inputString(){
int n = 5;
int size = n;
char* const_str = (char*)malloc((n+1)*sizeof(char));
char* substring = (char*)malloc((n+n)*sizeof(char)); /*here*/
char*p;
while((fgets(const_str,n,stdin)!=NULL)&&(strchr(const_str,'\n')==NULL)){
strcat(substring,const_str);
size += n;
substring = (char*)realloc(substring,size*sizeof(char)); /*here*/
}
strcat(substring,const_str);
size += n;
substring = (char*)realloc(substring,size*sizeof(char)); /*here*/
/*
printf("<%s> is \n",const_str);
printf("%s is \n",substring);
printf("%d is \n",size);
*/
if ((p=strchr(substring,'\n'))!=NULL){
p[0]='\0';
}
if(feof(stdin)){
changeToFull();
}
return substring;
}
and it will not be work on valgrind.
I guess, that i have memory leak here, but, i can't see any good solution to rewrite this function for valgrind.
Please, help!

I haven't tried it, but I found this on a question on SO:
--input-fd=<number> [default: 0, stdin]
Specify the file descriptor to use for reading input from the
user. This is used whenever valgrind needs to prompt the user
for a decision.
Original question here: making valgrind able to read user input when c++ needs it
EDIT:
So for your case, you may try:
mkfifo /tmp/abcd
exec 3</tmp/abcd
valgrind_command...... --input-fd=3
& in another terminal, use
cat > /tmp/abcd

Related

Segmentation fault - weird debugging with gdb

I'm working in C, Linux terminal. I need to find a pattern in a text and recolor it. GDB debugging can locate the function that is causing the problem via (gdb) backtrace, but it shows me a terrible message when I try to find the exact line:
Error
Program received signal SIGSEGV, Segmentation fault.
strstr_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strstr-sse2-unaligned.S:40
40 ../sysdeps/x86_64/multiarch/strstr-sse2-unaligned.S: No such file or dir
ectory.
(gbd)
The broken function is find_and_recolor:
char* my_replace(char *text, char* replacement)
{
int lgreplacement = strlen(replacement);
int lgtext = strlen(text);
char *aux = (char*)malloc((lgreplacement + lgtext + 10) * sizeof(char));
strcpy(aux, replacement);
strcat(aux, text);
return(aux);
}
char* find_and_recolor(char* text, char* pattern)
{
int lgpattern = strlen(pattern);
int lgreplace = lgpattern + 10;//there are exactly 10 characters that must be inserted along the pattern word
int dif = 0;
char *p;
char *replacement = (char*)malloc(lgreplace * sizeof(char));
strcpy(replacement, "\e[0;31m");
strcat(replacement, pattern);
strcat(replacement, "\e[m");//to recolor a word in red, that word must be surrounded by those characters
while(p = strstr(text + dif, pattern))
{
p = my_replace(p, replacement);
p += lgreplace;
dif = p - text;
}
free(replacement);
return strdup(text);
}
it shows me a terrible message when I try to find the exact line:
There is nothing terrible, weird or unusual about this message, you just need to learn proper debugging technique.
What's happening is that the segmentation fault doesn't happen in your code, it happens inside GLIBC code (inside strstr), because you called strstr with bad arguments.
To find which call to strstr that was, use GDB up command to step out of GLIBC code, and into your code. Once you are inside find_and_recolor, you would be able to see the exact line, and print values of text, dif and pattern which caused your crash (assuming you compiled your code for debugging, i.e. with the -g flag).
Updating diff to p-text in while loop where both pointer points to different array doesn't make sense. It is undefined behavior.
Also code has other issues.
Uninitialized variable.
Less optimized as number of call can be reduced.

Segmentation fault while function call

I got a struct Chat
struct Chat
{
int m_FD;
int m_BindPort;
char m_NameLength;
char* m_Name;
char m_PeerCount;
char** m_PeerList;
} typedef Chat_t;
i'm initializing it with this function:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen+1));
strcpy(this->m_Name, name);
this->m_BindPort = bindPort;
this->m_PeerCount = peerCount;
this->m_PeerList = malloc(sizeof(char*) * peerCount);
for(int i=0; i<peerCount; i++)
{
this->m_PeerList[i] = malloc(sizeof(char) * 16); // enough for xxx.xxx.xxx.xxx\0
strcpy(this->m_PeerList[i], peerList[i]);
}
//Socket initialization for TCP connection...
//Commenting this out doesn't change anything so i'm hiding it for simplification
return 0;
}
After that i'm calling a second function
int chat_communicate(Chat_t* this)
{
printf("2\n");
fflush(stdout);
//Some stuff that doesn't matter because it isn't even called
return retVar;
}
in main like this
void main(void)
{
char* peerList[1];
char username[USERNAME_MAX_LEN];
int initRet;
int loopRet;
Chat_t chat;
peerList[0] = "192.168.2.2";
memset(username, 0, USERNAME_MAX_LEN);
printf("Please enter your user name: ");
scanf("%s", username);
username[USERNAME_MAX_LEN-1] = 0;
initRet = chat_init(&chat, strlen(username), username, 1234, 1, peerList);
printf("File Descriptor: %d\n", chat.m_FD);
printf("Binding Port: %d\n", chat.m_BindPort);
printf("Name Length: %d\n", chat.m_NameLength);
printf("Name: %s\n", chat.m_Name);
printf("Peer Count: %d\n", chat.m_PeerCount);
for(int i=0; i< chat.m_PeerCount; i++)
{
printf("Peer[%d]: %s\n", i, chat.m_PeerList[i]);
}
printf("1");
ret = chat_communicate(&chat);
//Even more Stuff that isn't even called
}
My program outputs the following
File Descriptor: 3
Binding Port: 1234
Name Length: 4
Name: User
Peer Count: 1
Peer[0]: 192.168.2.2
1
Segmentation Fault
It compiles without errors or even warnings.
You can also assume that every string is null-Terminated The stuff i replaced with comments itn't that complicated but just too much to show.
Every value inside the struct is printed with printf right before but when passing this very struct per reference the application crashes.
What i want to know is why i'm getting this Segmentation Fault. Since it appeared while calling a function i thought it is some kind of layout problem but i havn't find anything like that.
Addition:
Because some people weren't able to believe me that the code i hid behind "some stuff" comments doesn't change anything i want to state this here once again. This code just contains a tcp socket communication and only performs read-operations. I also am able to reproduce the error mentioned above without this code so please don't get stuck with it. Parts does not influence the object under observation at all.
Among other potential problems,
this->m_PeerList = malloc(sizeof(char)*peerCount);
is clearly wrong.
m_PeerList is a char **, yet you're only allocating peerCount bytes, which only works if a char * pointer is one byte on your system - not likely.
Replace it with something like
this->m_PeerList = malloc(peerCount * sizeof( *( this->m_peerList ) ) );
Note that sizeof( char ) is always one - by definition.
You're not allocating enough memory for the this->m_Name. It should be on more than this if you want it to store the null-terminated string of the name.
That, or we need more information about the peerList.
Now that you have posted an almost complete code, I was able to spot two problems next to each other:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen + 1)); // correct
//< this->m_Name = malloc(sizeof(char) * nameLen); // wrong
strcpy(this->m_Name, name); // correct
//< memcpy(this->m_Name, name, nameLen); // wrong
...
The lines starting with //< is your original code:
Here you don't allocate enough space, you need to account for the NUL terminator:
this->m_Name = malloc(sizeof(char) * nameLen);
And here you don't copy the NUL terminator:
memcpy(this->m_Name, name, nameLen);
You really need to be aware how strings work in C.
Why don't you debug it yourself. If using GCC, compile your code with options -g -O0. Then run it with gdb:
gdb ./a.out
...
(gdb) r
If it crashes do:
(gdb) bt
This will give exactly where it crashes.
Update: There may be potential problems with your code as found by other users. However, memory allocation related issues will not crash your application just on calling function chat_communicate. There could be different reasons for this behaviour ranging from stack overflow to improper compilation. Without seeing the whole code it is very difficult to tell. Best advice is to consider review comments by other users and debug it yourself.

How to pass an array of char's to a function in C

I'm making my own command prompt (school project) and I'm trying to keep track of the last 10 commands the user uses. So I have an array:
char* history[10];
From my understanding this means I have an array of pointers, which point to strings. My problem with this is that I have another variable, input that is the users input. But whenever the user inputs something new, then the value of input changes, meaning all of the strings in my array change to the user's new input.
I'm wondering how I can get around this?
I tried changing my array to the following:
char *history[10][MAX] //Where MAX = 256
Where I could instead use strcpy instead but I was unable to figure out how to input an array of arrays into a method, and then use strcpy to copy the string into the array of arrays.
Here is my current method:
char* updateHistory(char *history[], char command[], int histIndex) {
history[histIndex] = command;
return *history;
}
Any help on another solution or how to get my solution working?
Your array of pointers needs to point to heap allocated memory, it sounds as if you point to some buffer that changes
So something like this should work
#define MAX_HISTORY 10
char* history[MAX_HISTORY];
if (fgets(input, sizeof(input), stdin) != NULL)
{
input[strlen(input)-1] = '\0'; // remove \n
history[n++] = strdup(input); // allocates and copies the input string
if ( n == MAX_HISTORY )
{
// throw away the oldest and move pointers forward one step
}
}
strdup is conceptually the same as
malloc( ) + strcpy()
so when you move the pointers forward and when you want clear the history you need to free() what the pointers point to.
Alternatively if you do not want to use the heap you could have a big buffer where you put the history
char history[MAX_HISTORY][MAX_CMD_LEN] but then you would need to shift more data and that is not so elegant/effective or have some elaborate indexing system to keep track of the contents
meaning all of the strings in my array change to the user's new input.
This happens probably because, you have a single variable to which command refers to inside updateHistory function. So anytime you make assignment on the first line of updateHistory function, all pointers in your array of pointers point to the same memory location - command.
To fix this, you need to allocate your array of pointers like this (for example you can do this outside your function):
char *history[10];
for ( i=0; i < 10; i++ )
{
history[i] = malloc(MAXLEN);
}
Then to copy string (this could go inside your function):
strcpy(history[i], command);
Also don't forget to free each variable in the array in the end.
While you are free to allocate space on the heap with malloc or calloc, if you are limiting your history to a reasonable size, a simple 2D statically declared character array can work equally well. For example:
#include <stdio.h>
#include <string.h>
/* constants for max pointers, max chars */
enum {MAXP = 10, MAXC = 256};
int main (void) {
char history[MAXP][MAXC] = {{0}};
char buf[MAXC] = {0};
size_t i, n = 0;
while (printf ("prompt > ") && fgets (buf, MAXC, stdin)) {
size_t buflen = strlen (buf);
buf[--buflen] = 0; /* strip newline */
/* check buflen to prevent saving empty strings */
if (!buflen) continue;
strncpy (history[n++], buf, buflen);
if (n == MAXP) /* handle full history */
break;
}
for (i = 0; i < n; i++)
printf (" history[%zu] : %s\n", i, history[i]);
return 0;
}
Example Use/Output
$ ./bin/fgets_static2d_hist
prompt > ls -al
prompt > mv a b/foo.txt
prompt > rsync ~/tmp/xfer hostb:~/tmp
prompt > du -hcs
prompt > cat /proc/cpuinfo
prompt > grep buflen *
prompt > ls -rt debug
prompt > gcc -Wall -Wextra -Ofast -o bin/fgets_static2d_hist fgets_static2d_hist.c
prompt > objdump obj/fgets_static2d.obj
prompt > source-highlight -i fgets_static2d.c -o fgets_static2d.html
history[0] : ls -al
history[1] : mv a b/foo.txt
history[2] : rsync ~/tmp/xfer hostb:~/tmp
history[3] : du -hcs
history[4] : cat /proc/cpuinfo
history[5] : grep buflen *
history[6] : ls -rt debug
history[7] : gcc -Wall -Wextra -Ofast -o bin/fgets_static2d_hist fgets_static2d_hist.c
history[8] : objdump obj/fgets_static2d.obj
history[9] : source-highlight -i fgets_static2d.c -o fgets_static2d.html
The benefit you get from a statically declared array is automatic memory management of your array storage and a slight benefit in efficiency from the memory being allocated from the stack. Either will do, it is just a matter of how much information you are managing.
When you want to pass array of pointer to a function, then you can use '&' sign to pass the address when you call a function.
For example:
This is what you have declared an array char* history[10];
This is the function you have used:
char* updateHistory(char *history[], char command[], int histIndex) {
history[histIndex] = command;
return *history;
}
So, while calling the function in the body of main(), call it like this
main()
{
updateHistory(&history, command, histIndex);
}
I hope this will help you out.. ok.

C hack: replace printf to collect output and return complete string by using a line buffer [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
Got this great C program I'd like to embed into an iOs app.
One passes command line arguments to it and the results are printed to stdout via printf and fputs - like with all the good old unix programs.
Now I'd like to just edit main and the print functions to use my own printf function which collects all the output that normally goes to stdout and return it at the end.
I implemented a solution by using a line buffer to collect all the printfs until the newline.
And a dynamic char array whereto I copy when an output line is finished.
The charm of this solution is - it's kind of tcl'ish: just throw everything into a text line and if its complete store it. Now do that as long as necessary and return the whole bunch at the end ...
And here the question:
It works - but as I am fairly new in "real" programming - i.e. C and Apples "brandnew" Swift - am not sure wheter this is a good solution. Is it? And if not - what would you suggest? Thank you very much!
Here follows the C code:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
// outLineBuffer collects one output line by several calls to tprntf
#define initialSizeOfReturnBuffer 10 // reduced for testing (would be 16*1024)
#define incrSizeOfReturnBuffer 5 // reduced for testing (would be 1024*1024)
#define outLineBufferMaxSize 4095
char outLineBuffer[sizeof(char)*outLineBufferMaxSize] = "";
char *tReturnString;
size_t sizeOfReturnBuffer, curPosOutBuffer = 0, lenOutLine = 0;
With the replacement tprntf for all the original printf and fputs:
// replace printf with this to collect the parts of one output line.
static int tprntf(const char *format, ...)
{
const size_t maxLen = sizeof(char)*outLineBufferMaxSize;
va_list arg;
int done;
va_start (arg, format);
done = vsnprintf (&outLineBuffer[lenOutLine], maxLen-lenOutLine, format, arg);
va_end (arg);
lenOutLine = strlen(outLineBuffer);
return done;
}
And the function when we complete one output line (everywhere \n is printed):
// Output line is now complete: copy to return buffer and reset line buffer.
static void tprntNewLine()
{
size_t newSize;
long remainingLenOutBuffer;
char *newOutBuffer;
remainingLenOutBuffer = sizeOfReturnBuffer-curPosOutBuffer-1;
lenOutLine = strlen(outLineBuffer)+1; // + newline character (\n)
remainingLenOutBuffer -= lenOutLine;
if (remainingLenOutBuffer < 0) {
newSize = sizeOfReturnBuffer + sizeof(char)*incrSizeOfReturnBuffer;
if ((newOutBuffer = realloc(tReturnString, newSize)) != 0) {
tReturnString = newOutBuffer;
sizeOfReturnBuffer = newSize;
} else {
lenOutLine += remainingLenOutBuffer; //just write part that is still available
remainingLenOutBuffer = 0;
}
}
snprintf(&tReturnString[curPosOutBuffer], lenOutLine+1, "%s\n", outLineBuffer);
curPosOutBuffer += lenOutLine;
outLineBuffer[0] = 0;
lenOutLine = 0;
}
And a little main to test it (without swift - e.g. plain gcc):
int main(int argc, char *argv[])
{
int i;
sizeOfReturnBuffer = initialSizeOfReturnBuffer*sizeof(char);
if ((tReturnString = malloc(sizeOfReturnBuffer)) == 0) {
return 1; // "Sorry we are out of memory. Please close other apps and try again!";
}
tReturnString[0] = 0;
for (i = 1; i < argc; i++) {
tprntf("%s ", argv[i]);
}
tprntNewLine();
tprntf("%s", "ABC\t");
tprntf("%d", 12);
tprntNewLine(); // enough space for that ;-)
tprntf("%s", "DEF\t");
tprntf("%d", 34);
tprntNewLine(); // realloc necessary ...
tprntf("%s", "GHI\t");
tprntf("%d", 56);
tprntNewLine(); // again realloc for testing purposes ...
printf("tReturnString at the end:\n>%s<\n", tReturnString); // contains trailing newline
return 0;
}
The call from swift will the be as follows (using CStringArray.swift)
let myArgs = CStringArray(["computeIt", "par1", "par2"])
let returnString = mymain(myArgs.numberOfElements, &myArgs.pointers[0])
if let itReturns = String.fromCString(returnString) {
print(itReturns)
}
freeMemory()
I am sure that tcl has many optimizations and I suggest you also optimize the code; then your approach can be viable.
Check your frequent use of strlen, which every time goes through all the (many) characters to count the length - use information about its length, for example maintain a char *outLineBufPtr. Also use strcat to append \n to outLineBuffer instead of using the expensive vsnprintf function, or just copy the char manually, as *outLineBufPtr++ ='\n'; .
To implement a higher-level concept such as yours, you must start thinking in machine cycles so the higher-level concept does not become "expensive".

Parsing commands shell-like in C

I want to parse user input commands in my C (just C) program. Sample commands:
add node ID
add arc ID from ID to ID
print
exit
and so on. Then I want to do some validation with IDs and forward them to specified functions. Functions and validations are of course ready. It's all about parsing and matching functions...
I've made it with many ifs and strtoks, but I'm sure it's not the best way... Any ideas (libs)?
I think what you want is something like this:
while (1)
{
char *line = malloc(128); // we need to be able to increase the pointer
char *origLine = line;
fgets(line, 128, stdin);
char command[20];
sscanf(line, "%20s ", command);
line = strchr(line, ' ');
printf("The Command is: %s\n", command);
unsigned argumentsCount = 0;
char **arguments = malloc(sizeof(char *));
while (1)
{
char arg[20];
if (line && (sscanf(++line, "%20s", arg) == 1))
{
arguments[argumentsCount] = malloc(sizeof(char) * 20);
strncpy(arguments[argumentsCount], arg, 20);
argumentsCount++;
arguments = realloc(arguments, sizeof(char *) * argumentsCount + 1);
line = strchr(line, ' ');
}
else {
break;
}
}
for (int i = 0; i < argumentsCount; i++) {
printf("Argument %i is: %s\n", i, arguments[i]);
}
for (int i = 0; i < argumentsCount; i++) {
free(arguments[i]);
}
free(arguments);
free(origLine);
}
You can do what you wish with 'command' and 'arguments' just before you free it all.
It depends on how complicated your command language is. It might be worth going to the trouble of womping up a simple recursive descent parser if you have more than a couple of commands, or if each command can take multiple forms, such as your add command.
I've done a couple of RDPs by hand for some projects in the past. It's a bit of work, but it allows you to handle some fairly complex commands that wouldn't be straightforward to parse otherwise. You could also use a parser generator like lex/yacc or flex/bison, although that may be overkill for what you are doing.
Otherwise, it's basically what you've described; strok and a bunch of nested if statements.
I just wanted to add something to Richard Ross's reply: Check the returned value from malloc and realloc. It may lead to hard-to-find crashes in your program.
All your command line parameters will be stored into a array of strings called argv.
You can access those values using argv[0], argv[1] ... argv[n].

Resources