I have read other threads on pset5 Valgrind memory errors, but that didn't help me. I get 0 leaks, but this instead:
==1917== Conditional jump or move depends on uninitialised value(s)
Looks like you're trying to use a variable that might not have a value? Take a closer look at line 34 of dictionary.c.
The error refers to line 34 which is this: lower[i] = tolower(word[i]);
To supply context, the code below attempts to check if a word exists in the dictionary that has been uploaded to a hash table. I am attempting to convert the wanted word to lowercase because all the dictionary words are also lowercase and so that their hashes would be identical. The program successfully completes all tasks, but then stumbles upon these memory errors.
Any hints as to why Valgrind is mad at me? Thank you!
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
Below is the whole dictionary.c file:
// Implements a dictionary's functionality
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table 26^3
const unsigned int N = 17576;
// Hash table
node *table[N];
int count = 0;
// Returns true if word is in dictionary else false
bool check(const char *word)
{
char lower[LENGTH + 1];
//Converts word to lower so the hashes of the dictionary entry and searched word would match
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
// Creates node from the given bucket
node *tmp = table[hash(lower)];
// Traverses the linked list
while (tmp != NULL)
{
if (strcasecmp(word, tmp->word) == 0)
{
return true;
}
tmp = tmp->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// Modified hash function by Dan Berstein taken from http://www.cse.yorku.ca/~oz/hash.html
unsigned int hash = 5381;
int c;
while ((c = *word++))
{
hash = (((hash << 5) + hash) + c) % N; /* hash * 33 + c */
}
return hash;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
FILE *inptr = fopen(dictionary, "r");
if (dictionary == NULL)
{
printf("Could not load %s\n.", dictionary);
return false;
}
// Create a char array to temporarily hold the new word (r stands for read)
char r_word[N+1];
// Until the end of file
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
// Hash the node
int index = hash(new_node->word);
// Places the node at the right index
new_node->next = table[index];
table[index] = new_node;
}
fclose(inptr);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
if (&load == false)
{
return '0';
}
else
{
return count;
}
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// Interates over the array
for (int i = 0; i < N; i++)
{
node *head = table[i];
while (head != NULL)
{
node *tmp = head;
head = head->next;
free(tmp);
}
}
return true;
}
This loop iterates through the maximum length of word-
for (int i = 0; i < LENGTH + 1; i++)
{
lower[i] = tolower(word[i]);
}
Except if you look at how word is created-
while (fscanf(inptr, "%s", r_word) != EOF)
{
// Increments count
count++;
// Create a node
node *new_node = malloc(sizeof(node));
if (new_node == NULL)
{
unload();
return false;
}
strcpy(new_node->word, r_word);
Notice, the variable r_word, may not be exactly of length LENGTH + 1. So what you really have in word is N number of characters, where N is not necessarily LENGTH + 1, it could be less.
So looping over the entire 0 -> LENGTH + 1 becomes problematic for words that are shorter than LENGTH + 1. You're going over array slots that do not have a value, they have garbage values.
What's the solution? This is precisely why c strings have \0-
for (int i = 0; word[i] != '\0'; i++)
{
lower[i] = tolower(word[i]);
}
This will stop the loop as soon as the NULL character is reached, which, you must have already learnt, marks the end of a string - aka a char array.
There may still be more errors in your code. But for your particular question - reading out of bounds is the answer.
I'm working on zk-proofs , but my solidity code returned an error as the title tell .
I have no idea about this situation , does anyone have some ideas?
this is my solidity function code
function stringToUint256(string memory s) internal pure
returns (uint256, bool) {
bool hasError = false;
bytes memory b = bytes(s);
uint256 result = 0;
uint256 oldResult = 0;
for (uint i = 0; i < b.length; i++) { // c = b[i] was not needed
if (b[i] >= 48 && b[i] <= 57) {
// store old value so we can check for overflows
oldResult = result;
result = result * 10 + (uint256(bytes(b[i]) - 48) ;
// prevent overflows
if(oldResult > result ) {
// we can only get here if the result overflowed and is smaller than last stored value
hasError = true;
}
} else {
hasError = true;
}
}
return (result, hasError);
}
I’m not familiar with solidity, but from just looking at the code, I think you’re missing a bracket in the following line:
result = result * 10 + (uint256(bytes(b[i]) - 48) ;
The brackets around the (uint...) part are incomplete. This might be what’s causing the syntax error; the program isn’t expecting a semicolon before the closing bracket.
I a trying to get a list of running processes using KVM, BSD. But I'm getting an EXC_BAD_ACCESS error in my NSLog Statement. How do I deal with it?
int main(int argc, char *argv[]) {
#autoreleasepool {
struct kinfo_proc *procs;
size_t count;
int err = GetBSDProcessList(&procs, &count);
if (err) return err;
for (size_t i=0; i!=count; ++i) {
NSLog(#"%d\n", procs[i].kp_proc.p_pid);
}
free(procs);
}
}
Please help.
I don't know where did you get GetBSDProcessList function but with a litle bit of search I have found an implementation and following code works fine:
#import <Foundation/Foundation.h>
#import <sys/sysctl.h>
typedef struct kinfo_proc kinfo_proc;
static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount);
int main(int argc, const char *argv[]) {
#autoreleasepool {
kinfo_proc *procList;
size_t count;
int err = GetBSDProcessList(&procList, &count);
if (err) return err;
for (size_t i = 0; i != count; ++i) {
NSLog(#"%d\n", procList[i].kp_proc.p_pid);
}
free(procList);
}
return 0;
}
static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
// Returns a list of all BSD processes on the system. This routine
// allocates the list and puts it in *procList and a count of the
// number of entries in *procCount. You are responsible for freeing
// this list (use "free" from System framework).
// On success, the function returns 0.
// On error, the function returns a BSD errno value.
{
int err;
kinfo_proc *result;
bool done;
static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
// Declaring name as const requires us to cast it when passing it to
// sysctl because the prototype doesn't include the const modifier.
size_t length;
assert(procList != NULL);
assert(*procList == NULL);
assert(procCount != NULL);
*procCount = 0;
// We start by calling sysctl with result == NULL and length == 0.
// That will succeed, and set length to the appropriate length.
// We then allocate a buffer of that size and call sysctl again
// with that buffer. If that succeeds, we're done. If that fails
// with ENOMEM, we have to throw away our buffer and loop. Note
// that the loop causes use to call sysctl with NULL again; this
// is necessary because the ENOMEM failure case sets length to
// the amount of data returned, not the amount of data that
// could have been returned.
result = NULL;
done = false;
do {
assert(result == NULL);
// Call sysctl with a NULL buffer.
length = 0;
err = sysctl((int *) name, (sizeof(name) / sizeof(*name)) - 1,
NULL, &length,
NULL, 0);
if (err == -1) {
err = errno;
}
// Allocate an appropriately sized buffer based on the results
// from the previous call.
if (err == 0) {
result = malloc(length);
if (result == NULL) {
err = ENOMEM;
}
}
// Call sysctl again with the new buffer. If we get an ENOMEM
// error, toss away our buffer and start again.
if (err == 0) {
err = sysctl((int *) name, (sizeof(name) / sizeof(*name)) - 1,
result, &length,
NULL, 0);
if (err == -1) {
err = errno;
}
if (err == 0) {
done = true;
} else if (err == ENOMEM) {
assert(result != NULL);
free(result);
result = NULL;
err = 0;
}
}
} while (err == 0 && !done);
// Clean up and establish post conditions.
if (err != 0 && result != NULL) {
free(result);
result = NULL;
}
*procList = result;
if (err == 0) {
*procCount = length / sizeof(kinfo_proc);
}
assert((err == 0) == (*procList != NULL));
return err;
}
I am running this code on Mac OS X Mojave Beta 2 with Xcode 10 Beta 2 and here is somple console output:
.
.
.
2018-06-22 11:22:59.540990+0300 ProcessList[2407:96970] 58
2018-06-22 11:22:59.541040+0300 ProcessList[2407:96970] 55
2018-06-22 11:22:59.541057+0300 ProcessList[2407:96970] 54
2018-06-22 11:22:59.541067+0300 ProcessList[2407:96970] 52
2018-06-22 11:22:59.541075+0300 ProcessList[2407:96970] 51
2018-06-22 11:22:59.541084+0300 ProcessList[2407:96970] 49
2018-06-22 11:22:59.541092+0300 ProcessList[2407:96970] 47
2018-06-22 11:22:59.541101+0300 ProcessList[2407:96970] 46
2018-06-22 11:22:59.541109+0300 ProcessList[2407:96970] 45
2018-06-22 11:22:59.541134+0300 ProcessList[2407:96970] 42
2018-06-22 11:22:59.541257+0300 ProcessList[2407:96970] 41
2018-06-22 11:22:59.541280+0300 ProcessList[2407:96970] 1
2018-06-22 11:22:59.541290+0300 ProcessList[2407:96970] 0
Program ended with exit code: 0
here is my code ( Mask_makeMask function) :
unsigned char *Mask_makeMask(int width, unsigned char *frame,
int *mask, HXecLevel level,int version,int autoMask)
{
unsigned char *masked;
unsigned char *tempmask;
int temp;
int maskv[4];
int maskval = *mask;
if(autoMask == 1)
{
tempmask = (unsigned char *)malloc(width * width);
if(tempmask == NULL) return NULL;
//>>>>>mask 00 process Mask_evaluate is to generate the marsk
maskv[0] = Mask_evaluate(width,frame);
//mask 01
maskMakers[0](width, frame, tempmask);
maskv[1] = Mask_evaluate(width,tempmask);
//mask 02
memset(tempmask,0,sizeof(tempmask));
maskMakers[1](width, frame, tempmask);
maskv[2]= Mask_evaluate(width,tempmask);
//mask 03
memset(tempmask,0,sizeof(tempmask));
maskMakers[2](width, frame, tempmask);
maskv[3] = Mask_evaluate(width,tempmask);
temp = maskv[0];
maskval = 0;
int i;
for(i= 1 ;i<4;i++)
{
if(temp >= maskv[i])
{
maskval = i;
temp = maskv[i];
}
}
}
else
{
tempmask = (unsigned char *)malloc(width * width);
if(tempmask == NULL) return NULL;
if(maskval ==0)
Mask_evaluate(width,frame);
else if( maskval >0 && maskval <=3)
{
maskMakers[maskval-1](width, frame, tempmask);
Mask_evaluate(width,tempmask);
}
free(tempmask);
}
>masked = (unsigned char *)malloc(width * width);#line 4319 valgrind
shows this is an error
>if(masked == NULL)
>{
> return NULL;
>}
if(maskval ==0 )
{
memcpy(masked,frame,width * width);
}
else
maskMakers[maskval-1](width, frame, masked);
Mask_writeInformation(width, masked, maskval, level,version);
*mask = maskval;
if(autoMask == 1)
free(tempmask);
return masked;
}
-------my code runs well but the valgrind log is blew:
==2570== Address 0x5c30429 is 0 bytes after a block of size 729 alloc'd
==2570== at 0x4024F20: malloc (vg_replace_malloc.c:236)
>==2570== by 0x410CB07: Mask_makeMask (barhanxin.c:4319)
==2570== by 0x410CF00: HXcode_encodeMask (barhanxin.c:4468)
1. I tried to initialize the masked by using memset(masked,0,width * width)
when the masked is not null, the HXcode_encodeMask called the
Mask_makeMask function,so I think the issue is Mask_makeMask, could anybody
give me some advice how to solve this issue?
I'm trying to read an intel .hex file using the following VHDL code snippet. My synthesizer is having a problem with the part of the code that is supposed to check for and discard the ':' character at the start of a line. The synthesis tool gives this error "Call to procedure without body" (line marked with comment). I have never seen this error and don't know what it means. Is there a solution for this error (or an alternate way to discard the ':' character)?
function Load_Data(constant x: in integer) return ROM_Data is
use std.textio.all;
use ieee.std_logic_textio.all;
file ROMFILE: TEXT open READ_MODE is "IIU_Code.hex";
variable newline: line;
variable newchar: character;
variable newbyte: std_logic_vector(7 downto 0);
variable newword: std_logic_vector(15 downto 0);
variable NextAddr, ByteCount: integer;
variable NewROM: ROM_Data := (others => (others => '0'));
variable valid: boolean := True;
begin
while (valid) loop
readline(ROMFILE, newline);
read(newline,newchar,valid); --ERROR HERE!!!
if (newchar = ':') and (valid = True) then
hread(newline,newbyte);
ByteCount := to_integer(unsigned(newbyte));
hread(newline,newword);
NextAddr := to_integer(unsigned(newword));
hread(newline,newbyte);
if newbyte = X"01" then --check for EOF marker
valid := False;
end if;
for i in 1 to ByteCount loop
hread(newline,newbyte);
NewROM(NextAddr) := newbyte;
NextAddr := NextAddr + 1;
end loop;
end if;
end loop;
file_close(ROMFILE);
return NewROM;
end;
In lieu of trying to force synthesis to initialize ROM from a file I've been known to write C programs that convert data for models to constants, in this case by generating entity/architecture pairs:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX_VECTOR 512
void rom_header (rom_name,array_size)
char *rom_name;
int array_size;
{
printf("library ieee;\nuse ieee.std_logic_1164.all;\n");
printf("\nentity %s is\n port (\n",rom_name);
printf("\tindex:\t\tin integer range 0 to %d;\n",array_size*8-1);
printf("\tOE:\t\tin std_logic;\n");
printf("\toutput:\t\tout std_logic_vector (7 downto 0)\n");
printf(" );\nend ;\n");
printf("\narchitecture behave of %s is\n\n",rom_name);
printf(" subtype bytestring is bit_vector( 7 downto 0);\n");
printf(" type bytestream is array (0 to %d) of bytestring;\n\n",
array_size*8-1);
printf(" constant byte_array:\tbytestream := (\n\t ");
}
void rom_tail() {
printf(" begin\n\n");
printf(" output <= To_StdLogicVector(byte_array(index)) ");
printf("when OE = '1' else\n");
printf(" (others => 'Z') ");
printf("when OE = '0' else\n");
printf(" (others => 'X');\n");
printf("\n\nend behave;\n\n");
}
int main (argc,argv)
int argc;
char *argv[];
{
extern char *optarg;
extern int optind, opterr;
extern int getopt();
char *infile;
char key_vector[MAX_VECTOR][16];
char plain_vector[MAX_VECTOR][16];
char cipher_vector[MAX_VECTOR][16];
char testinput[2047];
char testkey[17];
char testplain[17];
char testcipher[17];
int encrypt[MAX_VECTOR];
int i;
int len;
int testcount = 0;
int totalcount = 0;
int linenumber = 0;
int vector = 0;
int encode = 1;
while ( (i=getopt(argc,argv,"i:")) != -1 ) {
switch (i) {
case 'i':
infile = optarg;
if((freopen(optarg,"r",stdin)) == NULL) {
fprintf(stderr,"ERROR:%s, can't open %s for input\n",
argv[0],optarg);
exit(-1);
}
break;
case '?':
fprintf(stderr,"usage: %s [-i infile] \n",argv[0]);
fprintf(stderr,"\ngenerates VHDL arrays for DES test vectors:\n");
fprintf(stderr,"\tcipher_vector.vhdl\n");
fprintf(stderr,"\tencrypt_vector.vhdl\n");
fprintf(stderr,"\tkey_vector.vhdl\n");
fprintf(stderr,"\tplain_vector.vhdl\n");
exit (-1);
break;
}
}
while (fgets(testinput,(sizeof testinput) -1, stdin) != NULL ) {
linenumber++;
if ( strncmp(testinput,"encrypt",7) == 0) { /* mode = encode */
encode = 1;
fprintf(stderr,"%s",testinput);
}
else
if ( strncmp(testinput,"decrypt",7) == 0) { /* mode = decode */
fprintf(stderr,"%s",testinput);
encode = 0;
}
else
if ( strncmp(testinput," ",1) == 0) { /* key, plain & cipher */
testcount++;
len = sscanf(testinput,"%s%s%s*", testkey, testplain, testcipher);
if (len != 3) {
fprintf(stderr,"ERROR: %s, wrong vector count, line %d\n",
argv[0], linenumber);
exit(-1);
}
else if (strlen(testkey) != 16) {
fprintf(stderr,"ERROR: %s wrong byte count testkey, line %d\n",
argv[0],linenumber);
exit(-1);
}
else if (strlen(testplain) != 16) {
fprintf(stderr,"ERROR: %s wrong byte count testplain, line %d\n",
argv[0],linenumber);
exit(-1);
}
else if (strlen(testcipher) != 16) {
fprintf(stderr,"ERROR: %s wrong byte count testcipher, line %d\n",
argv[0],linenumber);
exit(-1);
}
else {
encrypt[vector] = encode;
strncpy( key_vector[vector], testkey,16);
strncpy( plain_vector[vector], testplain,16);
strncpy(cipher_vector[vector],testcipher,16);
for ( i = 0; i < 16; i++) {
if ( !isxdigit(key_vector[vector][i]) ||
!isxdigit(plain_vector[vector][i]) ||
!isxdigit(cipher_vector[vector][i]) ) {
fprintf(stderr,"ERROR: %s, Vector: %d contains nonhex\n",
argv[0], vector+1);
fprintf(stderr,"\t%s\n",testinput);
exit(-1);
}
}
}
vector++;
if (vector == MAX_VECTOR) {
fprintf(stderr,"%s: Maximum number of vectors = %d\n",
argv[0],MAX_VECTOR);
exit(0);
}
}
else { /* nothing but eyewash */
if ( testcount ) {
fprintf(stderr," %d test vectors\n",testcount);
totalcount +=testcount;
testcount = 0;
}
}
}
fprintf(stderr," Total: %d test vectors\n",totalcount);
if (freopen("key_vector.vhdl","w",stdout) == NULL){
fprintf(stderr,"ERROR: %s can write to key_vector.vhdl\n",argv[0]);
exit (-1);
}
rom_header("key_vector",totalcount);
for(vector = 0; vector < totalcount; vector++) {
for ( i = 0; i <= 15; i++) {
if ( !(i & 1)) {
printf("x\"%c",key_vector[vector][i]);
}
else {
if ( i < 15) {
printf("%c\",",key_vector[vector][i]);
}
else {
printf("%c\"",key_vector[vector][i]); // no comma
}
}
}
if (vector != totalcount-1)
printf(",\n\t ");
else
printf("\n\t);\n");
}
rom_tail();
if (freopen("plain_vector.vhdl","w",stdout) == NULL){
fprintf(stderr,"ERROR: %s can write to plain_vector.vhdl\n",argv[0]);
exit (-1);
}
rom_header("plain_vector",totalcount);
for(vector = 0; vector < totalcount; vector++) {
for ( i = 0; i <= 15; i++) {
if ( !(i & 1)) {
printf("x\"%c",plain_vector[vector][i]);
}
else {
if ( i < 15) {
printf("%c\",",plain_vector[vector][i]);
}
else {
printf("%c\"",plain_vector[vector][i]); // no comma
}
}
}
if (vector != totalcount-1)
printf(",\n\t ");
else
printf("\n\t);\n");
}
rom_tail();
if (freopen("cipher_vector.vhdl","w",stdout) == NULL){
fprintf(stderr,"ERROR: %s can write to cipher_vector.vhdl\n",argv[0]);
exit (-1);
}
rom_header("cipher_vector",totalcount);
for(vector = 0; vector < totalcount; vector++) {
for ( i = 0; i <= 15; i++) {
if ( !(i & 1)) {
printf("x\"%c",cipher_vector[vector][i]);
}
else {
if ( i < 15) {
printf("%c\",",cipher_vector[vector][i]);
}
else {
printf("%c\"",cipher_vector[vector][i]); // no comma
}
}
}
if (vector != totalcount-1)
printf(",\n\t ");
else
printf("\n\t);\n");
}
rom_tail();
if (freopen("encrypt_vector.vhdl","w",stdout) == NULL){
fprintf(stderr,"ERROR: %s can write to encrypt_vector.vhdl\n",argv[0]);
exit (-1);
}
printf("library ieee;\nuse ieee.std_logic_1164.all;\n");
printf("\nentity encrypt_vector is\n port (\n");
printf("\tindex:\t\tin integer range 0 to %d;\n",totalcount-1);
printf("\toutput:\t\tout std_logic\n");
printf(" );\nend ;\n");
printf("\narchitecture behave of encrypt_vector is\n\n");
printf(" constant bit_array:\tstd_logic_vector(0 to %d) := (\n\t ",
totalcount-1);
i = 0;
for(vector = 0; vector < totalcount; vector++) {
printf("'%1d'",encrypt[vector]);i++;
if ((i == 16) && (vector != totalcount-1)) {
printf(",\n\t ");
i = 0;
}
else if (vector == totalcount-1)
printf("\n\t);\n");
else
printf(",");
}
printf(" begin\n\n");
printf(" output <= bit_array(index);");
printf("\n\nend behave;\n\n");
exit (0);
}
You could also do this for packages or even subprograms.
This particular conversion software uses a form of valid vectors preceded by an encryption mode switch and having a first column space, providing hex values of the right string length:
#
encrypt
#
0101010101010101 95F8A5E5DD31D900 8000000000000000
0101010101010101 DD7F121CA5015619 4000000000000000
0101010101010101 2E8653104F3834EA 2000000000000000
0101010101010101 4BD388FF6CD81D4F 1000000000000000
0101010101010101 20B9E767B2FB1456 0800000000000000
0101010101010101 55579380D77138EF 0400000000000000
0101010101010101 6CC5DEFAAF04512F 0200000000000000
#
It's the test vectors for a byte wide interfaced DES chip, and in this case only used in a test bench. There's nothing stopping you from embedding something like you want.
This little C program is quite old but I believe I updated it recently enough it would compile and run, it spits out several different 'vector' files for the test bench based on what the values are used for. It wants the input file to be concluded with a comment line ('#' in the first column), followed by a newline.
So the message here is don't count directly on your synthesis tools to initialize data (unless they handle it with explicitly supported routines).
See How to synthesis a rom and load initial data into it ?, for a hint thread in Xilinx, otherwise noting you haven't specified target platform.
addendum
The questioner has been forthcoming with additional information in comments, wherein automated software has exhorted us to Please avoid extended discussions in comments.
The target is a Microsemi ProASIC3, which also prompted another look at the provided Load_Data function, whose input argument x doesn't show up in the function body. While that indicates the author may have been battling uphill restrictions trying to read a file.
Looking at Microsemi's web site we see that a ProASIC3 can have an embedded 1K bit FLASHROM, which may or may not be the ROM in question. I'm an ASIC designer from way back and can appreciate the size range of these devices, intended for among other uses System on Chip applications. You'd expect the vendor would be able to supply information on how to use the FLASHROM.
For other ROM purposes in lieu of vendor supplied method of loading ROM it would seem that creating a synthesis compatible method of embedding an array of constants is in order (analogous to what's shown in the C programming example).
One characteristic of Read Only Memory in programmable devices is that the values are typically included as part of device programming.