Heap buffer overflow error, Leetcode problem 941, Valid Mountain Array, using C - memory-leaks

I am currently learning c and trying to do some problems on leetcode to better myself.
The problem: https://leetcode.com/problems/valid-mountain-array/
I am getting an error as such, error message apperently a read error.
However whenever i run my code on my pc i don't get any errors, even using valgrind.
Here is my code:
bool validMountainArray(int* arr, int arrSize)
{
bool is_m_array = false;
bool peek = false;
int peek_point = 0;
int end_of_slope = 0;
int k = 0;
if( arrSize >= 3)
{
while (arr[k] < arr[k+1] && arr[k] < arrSize)
{
k++;
}
peek = true;
peek_point = k;
}
if (peek == true)
{
while(arr[peek_point] > arr[peek_point+1] && arr[peek_point] < arrSize)
{
peek_point++;
end_of_slope = peek_point+1;
printf("end Of SLOPE %d, arrSize %d \n", end_of_slope, arrSize);
}
}
if (peek == true && end_of_slope == arrSize)
{
is_m_array = true;
}
return is_m_array;
}
I have tried several different inputs and they all seem to work just fine!
For example:
int main(int argc, char const *argv[])
{ int arr[9]= {1,2,3,4,5,4,3,2,1};
if (validMountainArray(arr, 9) == true)
{
printf("True");
}
else
{
printf("False");
}
return 0;
}
Will return True.
Anyone got any ide what i am missing here?

Related

Processor implementation

Can you help me about the code below.
Is it writing 1 to the data memory or to the internal memory.
there are only 32 internal registers
The processor is 32 bit risc-v based
thanks in advance
#include "string.h"
#define DEBUG_IF_ADDR 0x00002010
void bubble_sort(int* arr, int len)
{
int sort_num;
do
{
sort_num = 0;
for(int i=0;i<len-1;i++)
{
if(*(arr+i) > *(arr+i+1))
{
int tmp = *(arr+i);
*(arr+i) = *(arr+i+1);
*(arr+i+1) = tmp;
sort_num++;
}
}
}
while(sort_num!=0);
}
int main()
{
int unsorted_arr[] = {195,14,176,103,54,32,128};
int sorted_arr[] = {14,32,54,103,128,176,195};
bubble_sort(unsorted_arr,7);
int *addr_ptr = DEBUG_IF_ADDR;
if(memcmp((char*) sorted_arr, (char*) unsorted_arr, 28) == 0)
{
//success
*addr_ptr = 1;
}
else
{
//failure
*addr_ptr = 0;
}
return 0;
}

PSET5 (Speller) Valgrind Error: Valgrind tests failed

I failed to pass the Valgrind tests and couldn't figure out what went wrong with my code. It seems like the issue is in the load() function as the Valgrind tests pointed out at the malloc() line. Could anyone help me take a look? Any guidance would be appreciated. Thank you!
Here is my code:
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// TODO: Choose number of buckets in hash table
const unsigned int N = 100;
// Hash table
node *table[N];
int count =0;
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
// TODO
int i = hash(word);
node *cursor = table[i];
if (table[i] == NULL)
{
return false;
}
else
{
while(cursor!= NULL)
{
if(strcasecmp(cursor->word, word) == 0)
{
return true;
}
else
{
cursor = cursor->next;
}
}
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO: Improve this hash function
int bucket;
if(word[1] != 0)
{
bucket = (((toupper(word[0])-'A') * (toupper(word[1]- 'A')))% 10 + (toupper(word[0])-'A'));
}
else
{
bucket = (((toupper(word[0])-'A') * (toupper(word[0])-'A'))%10 + (toupper(word[0])-'A'));
}
return bucket;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// TODO 1
//open the dictionary
FILE *file = fopen(dictionary, "r");
if(file == NULL)
{
printf("Can't load the dictionary\n");
return false;
}
//read string from file one at a time
char word[LENGTH + 1];
for (int i=0; i < N; i++)
{
table[i] = NULL;
}
while(fscanf(file, "%s", word) != EOF)
{
node *n = malloc(sizeof(node));
//create a new node for each word
if(n == NULL)
{
unload();
return false;
}
strcpy(n->word, word);
n->next = NULL;
count++;
char *c = n->word;
int number = hash(c);
if (table[number] != NULL)
{
//point the new node to the first node existing in the table
n->next = table[number];
//point the header to the new node
table[number] = n;
}
else
{
//n->next = NULL;
table[number] = n;
}
}
fclose(file);
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
return count;
//return 0;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
for (int i = 0; i > N; i++)
{
node *cursor = table[i];
while(cursor != NULL)
{
node *tmp = cursor;
cursor = cursor->next;
free(tmp);
}
free(cursor);
}
// TODO
return true;
}
Here is what the Valgrind tests show:
Valgrind tests
c.99 is this line -> node *n = malloc(sizeof(node));
The problem is in unload. It doesn't free any nodes. Review this line carefully and critically, it contains the error.
for (int i = 0; i > N; i++)

Find the word in the stream?

Given an infinite stream of characters and a list L of strings, create a function that calls an external API when a word in L is recognized during the processing of the stream.
Example:
L = ["ok","test","one","try","trying"]
stream = a,b,c,o,k,d,e,f,t,r,y,i,n,g.............
The call to external API will happen when 'k' is encountered, again when the 'y' is encountered, and again at 'g'.
My idea:
Create trie out of the list and navigate the nodes as you read from stream in linear time. But there would be a bug if you just do simple trie search.
Assume you have words "abxyz" and "xyw" and your input is "abxyw".In this case you can't recognize "xyw" with trie.
So search should be modified as below:
let's take above use case "abxyw". We start the search and we find we have all the element till 'x'. Moment you get 'x' you have two options:
Check if the current element is equal to the head of trie and if it is equal to head of trie then call recursive search.
Continue till the end of current word. In this case for your given input it will return false but for the recursive search we started in point 1, it will return true.
Below is my modified search but I think it has bugs and can be improved. Any suggestions?
#define SIZE 26
struct tri{
int complete;
struct tri *child[SIZE];
};
void insert(char *c, struct tri **t)
{
struct tri *current = *t;
while(*c != '\0')
{
int i;
int letter = *c - 'a';
if(current->child[letter] == NULL) {
current->child[letter] = malloc(sizeof(*current));
memset(current->child[letter], 0, sizeof(struct tri));
}
current = current->child[letter];
c++;
}
current->complete = 1;
}
struct tri *t;
int flag = 0;
int found(char *c, struct tri *tt)
{
struct tri *current = tt;
if (current == NULL)
return 0;
while(*c != '\0')
{
int i;
int letter = *c - 'a';
/* if this is the first char then recurse from begining*/
if (t->child[letter] != NULL)
flag = found(c+1, t->child[letter]);
if (flag == 1)
return 1;
if(!flag && current->child[letter] == NULL) {
return 0;
}
current = current->child[letter];
c++;
}
return current->complete;
}
int main()
{
int i;
t = malloc(sizeof(*t));
t->complete = 0;
memset(t, 0, sizeof(struct tri));
insert("weathez", &t);
insert("eather", &t);
insert("weather", &t);
(1 ==found("weather", t))?printf("found\n"):printf("not found\n");
return 0;
}
What you want to do is exactly what Aho-Corasick algorithm does.
You can take a look at my Aho-Corasick implementation. It's contest-oriented, so maybe not focused on readability but I think it's quite clear:
typedef vector<int> VI;
struct Node {
int size;
Node *fail, *output;
VI id;
map<char, Node*> next;
};
typedef pair<Node*, Node*> P;
typedef map<char, Node*> MCP;
Node* root;
inline void init() {
root = new Node;
root->size = 0;
root->output = root->fail = NULL;
}
Node* add(string& s, int u, int c = 0, Node* p = root) {
if (p == NULL) {
p = new Node;
p->size = c;
p->fail = p->output = NULL;
}
if (c == s.size()) p->id.push_back(u);
else {
if (not p->next.count(s[c])) p->next[s[c]] = NULL;
p->next[s[c]] = add(s, u, c + 1, p->next[s[c]]);
}
return p;
}
void fill_fail_output() {
queue<pair<char, P> > Q;
for (MCP::iterator it=root->next.begin();
it!=root->next.end();++it)
Q.push(pair<char, P> (it->first, P(root, it->second)));
while (not Q.empty()) {
Node *pare = Q.front().second.first;
Node *fill = Q.front().second.second;
char c = Q.front().first; Q.pop();
while (pare != root && !pare->fail->next.count(c))
pare=pare->fail;
if (pare == root) fill->fail = root;
else fill->fail = pare->fail->next[c];
if (fill->fail->id.size() != 0)
fill->output = fill->fail;
else fill->output = fill->fail->output;
for (MCP::iterator it=fill->next.begin();
it!=fill->next.end();++it)
Q.push(pair<char,P>(it->first,P(fill,it->second)));
}
}
void match(int c, VI& id) {
for (int i = 0; i < id.size(); ++i) {
cout << "Matching of pattern " << id[i];
cout << " ended at " << c << endl;
}
}
void search(string& s) {
int i = 0, j = 0;
Node *p = root, *q;
while (j < s.size()) {
while (p->next.count(s[j])) {
p = p->next[s[j++]];
if (p->id.size() != 0) match(j - 1, p->id);
q = p->output;
while (q != NULL) {
match(j - 1, q->id);
q = q->output;
}
}
if (p != root) {
p = p->fail;
i = j - p->size;
}
else i = ++j;
}
}
void erase(Node* p = root) {
for (MCP::iterator it = p->next.begin();
it != p->next.end(); ++it)
erase(it->second);
delete p;
}
int main() {
init();
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
string s;
cin >> s;
add(s, i);
}
fill_fail_output();
string text;
cin >> text;
search(text);
erase(root);
}

How to compare string variable to constant string in visual c++?

I have this piece of code:
#include "stdafx.h"
#include "afx.h"
...
char * connectionType;
...
int readParameters() {
...
//hFile is a file handler previously initialized
result = readParameter(hFile, connectionType);
if (strcmp(connectionType, "3") == 0) {
//do something
} else {
//do other thing
}
...
}
int readParameter(HANDLE hFile, OUT char * buffer) {
BOOL bResult = true;
BOOL continueLine = true;
char inBuffer[1];
DWORD bytesToRead = 1;
DWORD bytesRead = 0;
OVERLAPPED stOverlapped = {0};
char parameter[256] = {};
int counter = 0;
while (continueLine) {
bResult = ReadFile(hFile, inBuffer, sizeof(char), &bytesRead, &stOverlapped);
if (!bResult) {
return 0;
} else if (inBuffer[0] == '\n' || bytesRead == 0) {
continueLine = false;
} else {
parameter[counter] = inBuffer[0];
counter++;
if (bResult && bytesRead == 0) {
continueLinea = false;
}
}
}
parameter[counter] = '\0';
memcpy(buffer, parameter, 256);
return 1;
}
By debugging, I know that the connectionType attribute ends up being a null terminated string "3", but the strcmp method keeps returning 3328 (>0). Is there a problem because "3" is a constant? What might be the problem?
I realized what was the problem with the code. The problem was that connectionType, whose value was a null terminated string "3", was in fact different to the line read from the file, which was actually a "3" plus a carriage return plus a null.
After I added that consideration to the code, my problem was solved.

C, convert hex number to decimal number without functions

i'm trying to convert hexadecimal number to decimal number. What i've come up so far is:
#include <unistd.h>
#include <stdio.h>
long convert(char *input, short int *status){
int length = 0;
while(input[length])
{
length++;
}
if(length = 0)
{
*status = 0;
return 0;
}
else
{
int index;
int converter;
int result = 0;
int lastNumber = length-1;
int currentNumber;
for(index = 0; index < length; index++){
if(index == 0)
{
converter = 1;
}
else if(index == 1)
{
converter = 16;
}
else{
converter *= 16;
}
if(input[lastNumber] < 45 || input[lastNumber] > 57)
{
*status = 0;
return 0;
}
else if(input[lastNumber] > 45 && input[lastNumber] < 48)
{
*status = 0;
return 0;
}
else{
if(input[lastNumber] == 45)
{
*status = -1;
return result *= -1;
}
currentNumber = input[lastNumber] - 48;
result += currentNumber * converter;
lastNumber--;
}
}
*status = -1;
return result;
}
}
int main(int argc, char **argv)
{
char *input=0;
short int status=0;
long rezult=0;
if(argc!=2)
{
status=0;
}
else
{
input=argv[1];
rezult=convert(input,&status);
}
printf("result: %ld\n", rezult);
printf("status: %d\n", status);
return 0;
}
Somehow i always get resoult 0. Ia am also not allowed to use any other outher functions (except printf). What could be wrong with my code above?
This:
if(dolzina = 0)
{
*status = 0;
return 0;
}
is not merely testing dolzina, it's first setting it to 0. This causes the else clause to run, but with dolzina equal to 0 which is not the expected outcome.
You should just use == to compare, of course.

Resources