I am working on this project and when I run valgrind on this line of code
int numPointers;
numPointers = atoi(argv[NUM_POINTERS_VALUE]);
I get a valgrind error of
Invalid read of size 1 [PID: 8979]
Address 0x0 is not stack'd, malloc'd or (recently) freed
I was wondering what is going on here and if there is a way to fix it
When you are using command line arguments it is always a good practice to use
int main()
{
if(argc != <required number of argument>)
{
printf("Fewer arguments in the input\n");
return 1;
}
// Do your stuff
}
Later
if(argc[1] != NULL)
numPointers = atoi(argv[1]);
Because atoi(NULL) results in undefined behavior leading to crash.
Related
Here is the code and valgrind report. What am I doing wrong? This is code for comment remover written in C. I tried to look former threads about invalid read size and segfault, but I didn't really get the hang of my problem. I know I malloc too much memory if any comments are removed, but I don't think that should cause problems should it?
edit: If you need the main function which is used for testing this I can attach it too.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *delete_comments(char *input) {
unsigned int i = 0;
unsigned int a = 0;
char* dest = malloc( (strlen(input) + 1) * sizeof(char) );
while (i < strlen(input)) {
if(input[i] == '/' && input[i + 1] == '/') {
while (input[i - 1] != '\n') {
}
}
else if (input[i] == '/' && input[i+1] == '*') {
while (input[i-1] != '*' || input[i] != '/') {
i++;
}
}
dest[a] = input[i];
i++;
a++;
}
free(input);
return dest;
}
Build log:
make -C test valgrind
make[1]: Entering directory '/home/agent/test'
sed -e 's/int[ \t]\{1,\}main[ \t]*[(]/int _no_main(/g;s/void[ \t]\{1,\}main[ \t]*[(]/void _no_main(/g;s/^main[ \t]*[(]/_no_main(/g' ../src/source.c >../src/source.c.nomain.c
gcc -pthread -g -Wall -Wvla -std=c99 -o test test_source.c tmc-check.c checkhelp.c ../src/source.c.nomain.c -lcheck_pic -pthread -lrt -lm -lsubunit
valgrind -q --log-file=valgrind.log --track-origins=yes --leak-check=yes ./test
Running suite(s): Test-08_cleaner
0%: Checks: 1, Failures: 0, Errors: 1
test_source.c:67:E:test_delete_comments:test_delete_comments:0: (after this point) Received signal 11 (Segmentation fault)
make[1]: Leaving directory '/home/agent/test'
Valgrind output:
==44== Invalid read of size 1
==44== at 0x402FB9: delete_comments (source.c.nomain.c:19)
==44== by 0x401E3D: test_delete_comments (test_source.c:74)
==44== by 0x406DE2: srunner_run (in /home/agent/test/test)
==44== by 0x402492: tmc_run_tests (tmc-check.c:134)
==44== by 0x402127: main (test_source.c:206)
==44== Address 0x105b3cc4f is not stack'd, malloc'd or (recently) free'd
==44==
==44==
==44== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==44== Access not within mapped region at address 0x105B3CC4F
==44== at 0x402FB9: delete_comments (source.c.nomain.c:19)
==44== by 0x401E3D: test_delete_comments (test_source.c:74)
==44== by 0x406DE2: srunner_run (in /home/agent/test/test)
==44== by 0x402492: tmc_run_tests (tmc-check.c:134)
==44== by 0x402127: main (test_source.c:206)
==44== If you believe this happened as a result of a stack
==44== overflow in your program's main thread (unlikely but
==44== possible), you can try to increase the size of the
==44== main thread stack using the --main-stacksize= flag.
==44== The main thread stack size used in this run was 2048000
The segfault occurs here:
while (input[i - 1] != '\n') ...
Your counter i is an unsigned int. At the beginning you have i == 0 and i - 1 is a very large number, probably 2³² − 1. This might cause the segfault.
Note that Valgrind says that the address wasn't "stack'd, malloc'd". Usually, if you break the bounds of an array, it will say that the offending address is "one byte beyond malloc'd memory" or something similar.
Using unsigned ints as counters is a good choice, but be careful when you go backwards. In your case, you don't need to look backwards at all: You should advance beyond the // and then move forwards as long as required.
As an aside: Testing for strlen() in a loop condition is not a good idea in C, because strlen walks the whole string and looks for a null terminator. A smart compiler might optimize that, but it is better to calculate the string length once or, maybe better, test whether `input[i] != '\0'.
The terminating null is something you need to consider when skipping characters with a negated condition, too. For example, it is not enough to check whether the current character isn't a new-line. You must also make sure that it isn't the null terminator:
while (input[i] && input[i] != '\n') i++;
You have a perpetual loop in
while (input[i - 1] != '\n') {
}
This is not going anywhere. You at least need to update the loop variable i in every iteration.
I have this code, it's supposed to read a text file character by character and then do something with it, but the code keeps on segfaulting at line 6.
#include <stdio.h>
int main(void)
{
printf("a\n");
FILE* fp = fopen("~/pset5/dictionaries/small", "r");
for (int a = fgetc(fp); a != EOF; a = fgetc(fp))
{
printf("b\n");
}
return 0;
}
Something weird is definitely happening, because it doesn't even print "a\n" to the terminal, even tough the call to printf is before the error. I've run the program with gdb, and this is where it fails.
6 for (int a = fgetc(fp); a != EOF; a = fgetc(fp))
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
_IO_getc (fp=0x0) at getc.c:38
38 getc.c: No such file or directory.
I've also ran it with valgrind as in valgrind --leak-check=full ./test, with test being the name of the executable, and this is the relevant error message:
==7568== Invalid read of size 4
==7568== at 0x4EA8A21: getc (getc.c:38)
==7568== by 0x4005ED: main (test.c:6)
==7568== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==7568==
==7568==
==7568== Process terminating with default action of signal 11 (SIGSEGV)
==7568== Access not within mapped region at address 0x0
I'm really at a loss here, can someone explain what's going on with this segmentation fault, and why the hell isn't the first call to printf printing anything?
As the debugger says (fp=0x0), you're calling fgetc with a null pointer. This is what causes the crash.
fp is null because the fopen call failed. You need to check for errors.
Opening the file fails because most likely you do not have a directory called ~. Recall that expanding ~ to your home directory is done by the shell when you type a command. fopen only takes real filenames.
You forgot to check the return value of fopen() against NULL, which indicates an error while attempting to open the file.
Your for loop busily uses a NULL pointer, hence you get segfault.
Check the global variable errno to find out more about what exactly went wrong in your case.
So sort of new to C and I am trying to make a listener so that User has to press enter twice to completed typing there input. Then split by the new line and run all the data through a loop and send them through my functions.
I am not sure what i am doing wrong but when the loop right under "//segfaulting at loop" in the code is commented out it runs fine but when I uncomment it and have my call to "// assemble(ftemp);" commented it out it is segfaulting so i know it here just dont know what. Valgrind says the below if that helps at all.
Thanks In Advanced Pete.
==14639== Invalid read of size 1
==14639== at 0x4E7754C: ____strtod_l_internal (strtod_l.c:608)
==14639== by 0x4011F8: main (in /home)
==14639== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==14639== Process terminating with default action of signal 11 (SIGSEGV)
==14639== Access not within mapped region at address 0x0
==14639== at 0x4E7754C: ____strtod_l_internal (strtod_l.c:608)
==14639== by 0x4011F8: main (in /home)
==14639== If you believe this happened as a result of a stack
==14639== overflow in your program's main thread (unlikely but
==14639== possible), you can try to increase the size of the
==14639== main thread stack using the --main-stacksize= flag.
==14639== The main thread stack size used in this run was 8388608.
==14639== HEAP SUMMARY:
==14639== in use at exit: 0 bytes in 0 blocks
==14639== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==14639== All heap blocks were freed -- no leaks are possible
==14639== For counts of detected and suppressed errors, rerun with: -v
==14639== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
My code:
int main(int argc, char * argv[]) {
printf("Please Enter In Float (Hit Enter Twice To Exicute)\n" );
#define MAXLENGTH 1000
char Input_string[MAXLENGTH];
int ilop = 0;
for(;;++ilop)
{
Input_string[ilop] = getchar();
if (ilop > 0 && Input_string[ilop] == '\n' &&
Input_string[ilop-1] == '\n') break;
}
Input_string[ilop] = 0;
char *pch;
// printf ("Splitting string \"%s\" into tokens:\n",Input_string);
pch = strtok (Input_string,"\n");
float ftemp = atof(pch);
//printf("price:, %f\n\n",ftemp);
assemble(ftemp);
//segfaulting at loop
while (pch != NULL)
{
pch = strtok (NULL, "\n");
ftemp = atof(pch);
printf("price:, %f\n\n",ftemp);
// assemble(ftemp);
}
return 0;
}
To expand on what Igal S. said, you’re first setting strtok inside the loop, then using it, and not checking it until the top of the loop. So, on the last iteration, it will set pch to NULL, then pass it to atof() without checking it.
You need something like (untested):
pch = strtok (Input_string, "\n");
while (pch != NULL)
{
/* ... */
pch = strtok (NULL, "\n");
}
There is a possibility of array out of bound access which might lead to undefined behavior.
In the for loop at the beginning add the check
if(ilop > 999)
{
break;
}
I have been programming for a while but I am new to C. I have this linked list implementation in ansi C that I need to test. I have narrowed the problem down to an issue with an invalid write. I ran the code through Valgrind and received the following output:
==18131== Invalid write of size 1
==18131== at 0x4C2C0CC: __GI_strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64 linux.so)
==18131== by 0x40089B: main (in /home/btm7984/hw3/TestList)
==18131== Address 0x51f1388 is 0 bytes after a block of size 8 alloc'd
==18131== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18131== by 0x400880: main (in /home/btm7984/hw3/TestList)
==18131==
==18131== Invalid write of size 1
==18131== at 0x4C2C0DF: __GI_strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18131== by 0x40089B: main (in /home/btm7984/hw3/TestList)
==18131== Address 0x51f138e is 6 bytes after a block of size 8 alloc'd
==18131== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18131== by 0x400880: main (in /home/btm7984/hw3/TestList)
==18131==
--18131-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--18131-- si_code=1; Faulting address: 0x6D4FCAA; sp: 0x402bdae00
All that I can ascertain from this is that I am allocating something wrong. I think it has to be with my strcpy line. I really don't know how to approach this question. What follows is my use of the LinkedLists interface. InitLinkedLists, AddToBackOfList, and DestroyList are all defined in that interface.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LinkedLists.h"
int main(int argc, char *argv[]) {
FILE *fp;
char tmpString[100];
LinkedLists *ListPtr = malloc(sizeof(LinkedLists));
ElementStructs *DataPtr;
LinkedListNodes* curr = malloc(sizeof(LinkedListNodes));
int counter = 0;
int Done = 0;
InitLinkedList(ListPtr);
fp = fopen(argv[1], "r");
if (!fp){
fprintf(stderr,"%s Cannot open file %s\n", argv[0], argv[1]);
exit(1);
}
do{
fscanf(fp,"%s",tmpString);
if (!feof(fp)) {
DataPtr = malloc(sizeof(DataPtr));
printf("%d %d : %d\n",counter,(int)strlen(DataPtr->str),(int)strlen(tmpString));
strcpy(DataPtr->str,tmpString);
DataPtr->index=counter;
AddToBackOfLinkedList(ListPtr, DataPtr);
counter++;
Done = 1;
} else {
Done = 0;
}
}while (Done);
In conclusion, I think strcpy is causing an invalid write and I don't know why.
Any help would be greatly appreciated. Thanks in advance.
EDIT: ElementStructs is defined as follows:
typedef struct ElementStructs
{
/* Application Specific Definitions */
int index;
char str[100];
} ElementStructs;
The problem resides in this statement:
DataPtr = malloc(sizeof(DataPtr));
You allocate only enough memory to hold a pointer and not a full struct.
You should allocate using:
DatapPtr = malloc(sizeof(ElementStructs));
or, as described in the comments (WhozCraig):
DatapPtr = malloc(sizeof(*DataPtr));
Valgrind output:
GET /cs3157/tng/index.html
==760== Invalid read of size 1
==760== at 0x4C2E7D4: strstr (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==760== by 0x400E67: HandleTCPClient (http-server.c:101)
==760== by 0x400D42: main (http-server.c:75)
==760== Address 0x0 is not stack'd, malloc'd or (recently) free'd
Relevant code:
FILE *input = fdopen(clntSocket, "r"); //socket wrapped with FILE *
if (input == NULL)
{
perror("fdopen failed");
fclose(input);
return;
}
char request_buffer[100];
char out_buf[BUF_SIZE];
int len, res;
while( fgets(request_buffer, sizeof(request_buffer),input) != NULL)
{
request_buffer[sizeof(request_buffer)-1] = '\0'; //null terminates buffer
char *request = request_buffer;
char *token_separators = "\t \r\n"; // tab, space, new line
char *method = strtok(request, token_separators);
char *requestURI = strtok(NULL, token_separators);
char *httpVersion = strtok(NULL, token_separators);
if( strstr(method,"GET") != NULL )
{
if( requestURI[strlen(requestURI)] == '/' )
requestURI = strcat(requestURI,"index.html");
printf("%s %s\n", method, requestURI);
}
memset(request_buffer,'\0',sizeof(request_buffer) );
}
fclose(input); //close the socket by closing the FILE * wrapper
I read that this error is typically caused by failure to null terminate the String. I thought that my first line after fgets() would prevent that from being a problem. I'm guessing I'm overlooking something. I appreciate any help.
edit: Program ends crashes with a segmentation fault.
It sounds (from Valgrind's report) as if method is NULL. You should step through this code with a debugger to verify that the tokenizing works as intended.
Also, you should declare all those pointers as const char * since they're not intended to be written to. This is of course a minor point, but I try to encourage use of const whenever possible. :)
Address 0x0 is not stack'd, malloc'd or (recently) free'd
Something is wrong here: the program seems to be dereferencing NULL. I'm wondering whether it does segfault in the end - you should check return values of strtok(), as it returns NULL in case no more tokens are found.