C-strdup memory leak - c

I have this code here and when I run it it works normally but at the end it throws me a memory leak from the strdup function.
Could I ask for some advice, I'm at my wits end.
My code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
void modify(const char *input, char *output) {
int lng = strlen(input);
for (int i = 0; i < lng - 1; ++i) {
output[i] = input[i];
}
}
typedef struct {
int index;
char *ticker;
float start;
float end;
int volume;
} Akcie;
void akcie_init(Akcie *akcie, int index, char *ticker, float start, float end, int volume) {
akcie->index = index;
akcie->ticker = ticker;
akcie->start = start;
akcie->end = end;
akcie->volume = volume;
}
int main(int argc, char **argv) {
Akcie *akcie;
char *com;
if (argc == 3) {
int cislo = atoi(argv[2]);
akcie = (Akcie *) malloc(cislo * sizeof(Akcie));
char buf[101];
char lo[100];
char *toto[5];
printf("<html>\n"
"<body>\n"
"<div>\n"
"</div>\n"
"<ul>\n");
for (int i = 0; i < cislo; ++i) {
fgets(buf, sizeof(buf), stdin);
modify(buf, lo);
com = strdup(lo);
int j = 0;
char *colo = strtok(com, ", ");
while (colo != NULL) {
toto[j] = colo;
colo = strtok(NULL, ", ");
j++;
}
akcie_init(&akcie[i], akcie[i].index = atoi(toto[0]), akcie[i].ticker = toto[1],
akcie[i].start = atof(toto[2]), akcie[i].end = atof(toto[3]), akcie[i].volume = atoi(toto[4]));
}
for (int l = cislo - 1; l >= 0; l--) {
printf("<li> Day: %d, ticker: %s start: %.2f, end: %.2f, volume: %d </li> \n", akcie[l].index,
akcie[l].ticker, akcie[l].start, akcie[l].end, akcie[l].volume);
}
free(com);
free(akcie);
printf("</ul>\n"
"</body>\n"
"</html>");
} else {
printf("Wrong parameters");
}
}
Output + Memory leak
└─$ ./main AMC 10 <test-ticker-404.stdin
<html>
<body>
<div>
</div>
<ul>
<li> Day: 5, ticker: META start: 458.51, end: 462.19, volume: 328371639 </li>
<li> Day: 4, ticker: GOOGL start: 687.75, end: 690.60, volume: 84021759 </li>
<li> Day: 4, ticker: META start: 462.58, end: 458.51, volume: 536291890 </li>
<li> Day: 3, ticker: AAPL start: 408.75, end: 411.80, volume: 737451730 </li>
<li> Day: 3, ticker: GOOGL start: 687.98, end: 687.75, volume: 70074900 </li>
<li> Day: 3, ticker: META start: 461.47, end: 462.58, volume: 275445389 </li>
<li> Day: 2, ticker: AAPL start: 408.15, end: 408.75, volume: 475850689 </li>
<li> Day: 2, ticker: GOOGL start: 685.68, end: 687.98, volume: 91902769 </li>
<li> Day: 2, ticker: META start: 458.37, end: 461.47, volume: 19824825 </li>
<li> Day: 1, ticker: AAPL start: 403.28, end: 408.15, volume: 71579480 </li>
</ul>
</body>
=================================================================
==5879==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 277 byte(s) in 9 object(s) allocated from:
#0 0x7f4b1487077b in __interceptor_strdup ../../../../src/libsanitizer/asan/asan_interceptors.cpp:439
#1 0x55dd86eca65b in main main.c:46
#2 0x7f4b14429209 (/lib/x86_64-linux-gnu/libc.so.6+0x29209)
SUMMARY: AddressSanitizer: 277 byte(s) leaked in 9 allocation(s).
I was thinking to save the com in each stock and then at the end delete all those com indicators in the stock. Or even completely differently, not allocate memory on the heap, but store those names directly in the share, in the form of a static array. But I don't know how to do that. Thank you for the solution

It's a very obvious leak as you call com = strdup(lo); in an inner loop but only free in an outer loop.
The most basic rule of memory leaks: the number of malloc/strdup calls must match the number of free calls.

Related

Array: How to change specific values dependent on index (Rating function)

I'm sorry for the terrible title, but somehow I can't explain it better in one sentence.
What I want to do is a rating component in my Vue App. So if I click the 3rd star, the two stars before that one are set to "true" as well.
What I got:
const ratingsArray = [
{
name: 'rating1',
ratingCount: 1,
isClicked: ref(false)
},
{
name: 'rating2',
ratingCount: 2,
isClicked: ref(false)
},
{
name: 'rating3',
ratingCount: 3,
isClicked: ref(false)
},
{
name: 'rating4',
ratingCount: 4,
isClicked: ref(false)
},
{
name: 'rating5',
ratingCount: 5,
isClicked: ref(false)
},
]
I just got a toggle function to toggle isClicked:
function toggleClick(x) {
x.value = !x.value
}
This is my template
<template>
<div v-for="rating in ratingsArray"
:key="rating.name"
#click="toggleClick(rating.isClicked)"
:class="[rating.isClicked.value ? 'ratingBoxFilled' : 'ratingBox']">
</div>
</template>
How can I say, that if rating3 is clicked (so isClicked is true), rating1 and rating2 also got to be true?
It seems that I need to work with the index in my array. But somehow, I cannot create an idea. Maybe you guys can help me out. Thank you!
A simple loop would do the trick:
<template>
<div v-for="(rating, index) in ratingsArray"
:key="rating.name"
#click="toggleClick(index)"
:class="[rating.isClicked.value ? 'ratingBoxFilled' : 'ratingBox']">
</div>
</template>
function toggleClick(ratingIndex) {
for (let i = 0; i < ratingsArray.length; i++) {
// Set ratingsArray[i].isClicked to true if it's within the requested range
ratingsArray[i].isClicked.value = (i <= ratingIndex);
}
}
You guys are great. I didn't thought of an for loop.
So here is my final solution:
<div
v-for="(rating, index) in ratingsArray"
:key="rating.name"
#click="updateRating(index, rating.ratingValue)"
:class="[rating.isEnabled.value ? 'ratingBoxChecked' : 'ratingBox']">
</div>
function updateRating(ratingIndex: number, ratingValue: number) {
for (let i = ratingIndex; i < 5; i++) {
ratingsArray[i].isEnabled.value = false;
}
for (let i = 0; i <= ratingIndex; i++) {
ratingsArray[i].isEnabled.value = true;
}
console.log('Rating Value: ' + ratingValue)
}
First I clean all the enabled dots.
Then it will run until the given index and set the boolean value to true. Thats all.

rendering the array values only works in the initialization in vue2?

I have worked on vue2 with a simple demo, there is an array with values, by clicking the button, the array values will be shuffled. However rendering the array in html doesn't change at all after the shuffling.
<template>
<div>
<div #click="random()" > random </div>
{{ selected11.length }}
<div class="flex flex-grow " v-for="(item,index) in selected11" :key="index" >
{{ item }} {{ index }}
</div>
</div>
</template>
<script>
export default {
name: 'Choice',
data() {
return {
selected11:[],
}
},
created() {
this.selected11 = ['A', 'B', 'C', 'D','E'];
},
methods: {
random(){
console.log( 'random',this.selected11 );
this.selected11 = this.shuffle( this.selected11 );
console.log( this.selected11 );
},
shuffle(a) {
var j, x, i;
for (i = a.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = a[i];
a[i] = a[j];
a[j] = x;
}
return a;
}
}
}
</script>
The issue is in your shuffle method where reassignment of keys with values from key positions of its own referenced self is self-destructive and is causing a silent reactive fail.
The only way I can think of describing this is like a Wormhole is traveling into its self, in this circular event that warps its self out of existence...
You need to shuffle a clone of the original object and return this shuffled clone so it replaces the original object, otherwise the array eats its self.
shuffle(a) {
let j, x, i;
let shuffle = structuredClone(a)
for (i = shuffle.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = shuffle[i];
shuffle[i] = shuffle[j];
shuffle[j] = x;
}
return shuffle;
}

AngularJs- Calculation inside a controller

Hello I want to be able to calculate some numbers inside a controller that contains elements. This is what have tried (ionic APP too btw) :
.controller('tasksCtrl', function($scope) {
$scope.tasksCollection = [
{ info: 'Go studying', measured: 'no', total: 1, done: 1, id: 1 },
{ info: 'Go to the beach', measured: 'no', total: 1, done: 1, id: 2},
{ info: 'Run', measured: 'yes', total: 30, done: 15, id: 3}
];
$scope.calculateProductivity = function(){
var total = 0;
for(var i = 0; i < $scope.tasksCollection.length; i++){
var product = $scope.tasksCollection[i];
total += (tasksCollection.done / tasksCollection.total);
}
return total;
};
})
and the page has:
<div class="item tabs tabs-secondary tabs-icon-left">
<div ng-app="starter" ng-controller="tasksCtrl" class="tab-item tab-main-left">
<span class="title-red"> {{ calculateProductivity() }} </span><span class="medium-text">Productivity Ratio</span>
</div>
<div class="tab-item tab-main-right">
<span class="title-red">20 </span><span class="medium-text">PMoney</span>
</div>
</div>
On the output I only see "{{ calculateProductivity() }}" and not the result, but if I write tasksCollection.info it gets correctly displayed.
thanks!
you are calculating total as:
total += (tasksCollection.done / tasksCollection.total);
and it should probably be:
total += (product.done / product.total);
PLease see this: http://stackoverflow.com/questions/20942878/angularjs-use-a-function-in-a-controller-to-return-data-from-a-service-to-be-use
The following changes should work:
<span class="title-red"> {{ productivity_ratio }} </span><span class="medium-text">Productivity Ratio</span>
for(var i = 0; i < $scope.tasksCollection.length; i++){
var product = $scope.tasksCollection[i];
total += (tasksCollection.done / tasksCollection.total);
}
$scope.productivity_ratio = total;

angularjs execute expression from variable

How to execute expression from variable?
I need something like formula which depends from another inputs.
For example my data:
$scope.items = [{
name: 'first',
formula: '',
value: 1,
type: 'text',
},{
name: 'second',
formula: '',
value: 2,
type: 'text',
},{
name: 'third',
formula: '{first}+{second}',
type: 'formula',
}];
and my view:
<ul>
<li ng-repeat="item in items">
<div ng-switch on="item.type">
<div ng-switch-when="text">
<input type="text" ng-model="item.value" name="{{item.name}}">
</div>
<div ng-switch-when="formula">
<span>{{item.formula}}</span>
</div>
</div>
</li>
I want that the result was 3
But it's {first}+{second} ofcourse
<div ng-switch-when="formula">
<span>
{{getFormulaResult(item.formula)}}
</span>
</div>
Controller method:
$scope.getFormulaResult = function(formula){
var formulaSplits = formula.split("+");
var left = formulaSplits[0];
left = left.substr(1);
left = left.substring(0, left.length-1);
var right = formulaSplits[1];
right = right.substr(1);
right = right.substring(0, right.length-1);
var sum = 0;
for(var i = 0; i < $scope.items.length; i++){
if($scope.items[i].name == left || $scope.items[i].name == right){
sum = sum + parseInt($scope.items[i].value, 10);
}
}
return sum || 0;
}

Loop over and array and add a separator except for the last

Using Handlebarjs, I'd like to loop over an array, and display values, separated by a separator. It would be easy if the content I want to display wasn't a template too ;)
Here's my case :
accounts = [
{'name': 'John', 'email': 'john#example.com'},
{'name': 'Malcolm', 'email': 'malcolm#example.com'},
{'name': 'David', 'email': 'david#example.com'}
];
{{#each accounts}}
{{ name }},
{{/each}}
The problem with this implementation is that I will have this output :
John, Malcolm, David,
And I'd like it to be :
John, Malcolm, David
How can I do that ?
You can use CSS pseudo class :after, together with content, to achieve the required "formatting".
(:after and content support in most browser today, and IE8+.)
For example:
HTML:
Foo1
Foo2
Foo3
CSS:
a {
color: red;
}
a:after {
content: ", ";
}
a:last-child:after {
content: "";
}
Result:
Foo1, Foo2, Foo3
I implemented a new foreach helper that can do the trick :
Handlebars.registerHelper('foreach', function (array, fn) {
var total = array.length;
var buffer = '';
//Better performance: http://jsperf.com/for-vs-foreach/2
for (var i = 0, j = total; i < j; i++) {
var item = array[i];
// stick an index property onto the item, starting with 1, may make configurable later
item['_index'] = i+1;
item['_total'] = total;
item['_isFirst'] = (i === 0);
item['_isLast'] = (i === (total - 1));
// show the inside of the block
buffer += fn.fn(item);
}
// return the finished buffer
return buffer;
});
And then :
{{#foreach accounts}}
{{ name }}{{#unless _isLast}}, {{/unless}}
{{/foreach}}

Resources