I am given a task which is as follows:
User enters a string of symbols which can be only < (less), > (greater) or = (equal) and string ends with semicolon. The task is to generate numbers between those symbols while the very first number is 1. An example: if user enters <>>>=<; the program should generate numbers according to those symbols, like this: 1<2>1>0>-1=-1<0. In my program everything is working...sort of. Sometimes if I enter 15 symbols, everything works just fine, but when I enter 20 symbols, my program crashes so my guess is I have issues with memory allocation, but not sure where... Any help would be appreciated! Here is my code:
Problem solved!
sizeof(simboliai) returns size of the pointer (usually 4) not the actual length of allocated array. You need to keep track of that separately. For example, in another variable.
Related
I have a problem on SPOJ and a deadline soon.
I'm tasked to write a program that counts how many identifiers are in a given line. Identifier is defined a sequence of characters from set 'a'-'z' or 'A'-'Z' or '0'-'9' or '_', starting from any letter or underline character ('_').
Input
There are given some number of data sets. Each data set is a line consisting from the sequence of some number of words, separated by spaces and finishing with the end of line character (even the last one line). A word is a sequence of any ASCII character of code from 33 till 126 (see http://www.asciitable.com for more details), e.g., aqui28$-3q or _dat_ The second word is an identifier, but the first one is not.
Output
The number of identifiers in each line.
Example
Input:
Dato25 has 2 c-ats and 3 _dogs
op8ax _yu _yu67 great-job ax~no identifier.
Output:
4
3
The code I wrote compiles, but when submitting it returns SIGSEGV (Segmentation Fault).
Your code exhibits a lamentably common anti-pattern: unnecessarily reading a large chunk of data into memory before processing it, when it could instead be processed as you go.
Consider: when you're processing one input word, do you need to refer to previous or subsequent words of the same or any other line? No. So why are you keeping all that around in memory?
In fact, you don't need to store any part of any of the words, except a single character you have just read. You simply need to
track
how many identifiers you've seen so far on the current line and
what kind of thing you're parsing at any given time (possible identifier, non-identifier word, or spaces),
update that appropriately for each character read, and
emit appropriate output (based on the preceding) at the end of each line.
That is likely to be faster than your approach. It will certainly use less memory, and especially less stack memory. And it affords little to no room for any kind of bounds overrun or invalid pointer use, such as are the usual reasons for a memory error such as a segfault.
As to why your original program segfaults, I ran it using valgrind, which is a popular tool for identifying memory usage problems. It can detect memory leaks, some out-of-bounds accesses, and use of uninitialized memory, among other things. It showed me that you never initialize the ident_count of any line[i]. Non-static local variables such as your line are not automatically initialized to anything in particular. Sometimes you can luck out with that, and it's not the cause of your particular issue, but cultivate good programming practices: fix it.
Valgrind did not indicate any other errors to me, however, nor did your program segfault for me with the example input. Nevertheless, I anticipate that I could wreak all kinds of havoc in your program by feeding it input with more than 100 lines and / or more than 300 words in a line, and / or more than 50 characters in a word. Automated judges tend to include test cases that explore the extremes of the problem space, so you need to be sure that your program works for all valid inputs.
Alternatively, a valid point is made in comments that you are allocating a large object on the stack, and stack space may not be sufficient for it in the judge's test environment. If that's the issue, then a quick and easy way to resolve it in your current code would be to allocate only one struct WORDS and reuse it for every line. That will reduce your stack usage by about a factor of 100, and again, what purpose is served by storing all the lines in memory at the same time anyway?
The program needs to get input text and an option from the user. At this stage I am currently working on the ap: option which reads a text from the user and appends the corresponding data to the corresponding arrays. (Also I have to input the text with the option as a prefix, e.g. ap:Text, because that is how the bot that tests my program inputs it.).
Here is the code: https://gist.github.com/Kritsos/03d08f29beb97d24eba1cbc4e83962ab
I know it's a bit difficult to follow it so I will try to explain it as better as I can. First of all I know that there are a lot of memory leaks, I will tend to them as soon as I get the 3 functions working. I have tried to dynamically allocate almost everything (that's why I use triple pointers) and I hope that the allocation is correct and not the cause of the problems. The par function is supposed to get a paragraph from the input text which is easy because the input texts is a paragraph on its own so I just copy the text to the paragraph array. Now the sent and word functions are the ones I am having trouble with. Both are based on the same logic. I take the input text from the user, I try to find the ending character( ".!?;" for sentences " " for words), place a '\0' there, copy the string to the corresponding array then do the same thing but instead of checking the whole input text again I start from the position I placed the '\0' + 1.
Your code has numerous errors in it, the critical one that's causing your current crash are lines 8, 32, and 59. All variations on this:
**paragraphs = realloc(**paragraphs, *num_par * sizeof(char *));
You're calling realloc on pointers that were never allocated in the first place.
The lesson here isn't "be careful with pointers" or anything like that, though obviously you should be. The lesson is that tons of indirection becomes difficult to reason about. Rather than try to make a three-star solution work, you should explore a different approach that doesn't require these kinds of code gymnastics.
I have questions regarding the three redirect messages I got. Just to give some context to my program...
I am using C programming and Linux. I read numbers from a file containing all the words in a dictionary. I extract the words from the file and save them in a string object which consists of 3 things: a dynamically allocated array of characters for the words (the string objects are designed so that I do not need null terminators at the end of the arrays), an integer for the size of the word currently being stored, and an integer for the capacity of the current dynamically allocated array of characters. Each string object itself is stored in a vector, and I have an array of 30 vectors with the index of each vector corresponding to the size of the words. For example, index 2 in my array of vectors has 94 words which means the vector at index 2 contains 94 string objects with each object holding a word of size 2. After storing them in the vectors, I then print them to stdout (you can see the tail end of this), and then print out the size of each vector as well as the total words extracted.
Up until now (I'm a fairly new CS student so bear with me), I ran my code always with valgrind and --leak-check=full. As you can see, I have no memory leaks or errors. However, I became aware of the "-v" I could run my program with as well, and when I do that, I get the three redirect messages:
libc.so.6:__strlen_avx2
libc.so.6:__mempcpy_avx_unaligned_erms
libc.so.6:__strchrnul_avx2
I have no idea what these mean. I tried trying to figure it out for myself by looking it up online and I couldn't figure it out so I'm wondering what those errors mean. The last thing I'll say is, the first redirect message involves "strlen" which is a string library function in C's string.h library. However, I never use string.h. The whole point of this project was for me to create my own customized string objects and my own library of string functions to work with these string objects. So, assuming that the redirect message is referring to the string.h library function, I have no idea why it's doing that.
I didn't post any code since it's a long project. I'm just looking for answers as to in general what those messages could be referring to.
Valgrind will check the use of library functions too - such as strlen, memcpy, strchrnul.
When you compile with some optimizations enabled or otherwise, then these function calls might be replaced with an optimized version, i.e. here ones optimized for AVX and AVX2. But those functions are doing some dirty tricks that would otherwise be illegal in C, and also hard for valgrind to check. So valgrind reditrects the call to __strlen_avx2 back to strlen, so that valgrind can more easily track the specifics. Now, -v means only --verbose and it shows more information... and for some it might be crucial to know that the actual function __strlen_avx2 is not called at all, unlike when not run with valgrind, but any calls to that would jump to the strlen controlled by valgrind instead.
I am actually making an algorithm that takes as an input a file containing tetriminoses (figures from tetris) and arranges them in smallest possible square.
Still I encounter a weird problem :
The algorithm works for less than 10 tetriminoses (every time) but start crashing with 11, 12... (I concluded that it depends on how complicated the solution is, as it finds some 14 and 15 solutions).
But the thing is, if I add an optimisation flag like -Ofast (the program is written in C) it works for every input I give him no matter how much time it takes (sometimes more than a hour..).
First I had a lot of leaks (I was using double linked list) so I changed for an Int Array, no more leaks, but same problem.
I tried using the debugger but it makes no sense (see picture) :
Debugger says my variables do not exist anymore but all I do is increment or decrement them.
For this example it just stopped while everything is fine (values of variables are correct)
Here is the link of my main function (the one that do the backtracking):
https://github.com/Caribou123/fillitAG/blob/master/19canplace/solve.c
The rest of program (same repository) consist of functions to put tetriminoses in my array, remove them from it, or print the result.
Basically I try placing a tetri, if I have enough space, I place the next one, otherwise I remove the last one and place it to the next available position etc..
Also I first thought that I were trying to place something outside of the Array, so now my Array is way bigger than it should be and filled with -1 for invalid cases (so in the worst case I just rewrite a -1), 0 for free ones, and integers values from 1 to 26 for figures.
The fact that the program works with the flag -Ofast really troubles me, as the algorithm seems to work perfectly, what could cause my program to crash ?
Here is how I tracked the number of recursions, by adding two static variables
And here is the output
(In case you want to test it yourself, use the 19canplace folder, and compile with : gcc *.c libft/libft.a)
Thanks in advance for your time,
Artiom
I've been searching a while for this, and couldn't find an answer. I will be appreciated if someone knows how do to that!
PROBLEM: I must code a program that will store some numbers, but I don't know how much numbers there will be! What can I do?
I was wondering if I could use timing to get things done. I mean, if 5 secs has passed and there is no input of data, then start processing these numbers. It would work, but I couldn't code this. Can someone help, please?
1) first solution:
You can ask the user to enter the number of desired element at the beginning.
2) second solution:
Keep scan numbers till you get EOF from the user. and store the input number into a linked list or a dynamically allocated array (resize your array size withe the realloc)
3) third solution
keep scan numbers with a timeout. If there is no input during the timeout then the program will consider that the user have finished input numbers and then the program stop reading from stdin. The input numbers could stored into linked list or dynamic array as indicated in the second solution. Use select() with the scanf() in order to add the timeout behaviour as indicated in this answer