gpt4 book ai didi

c - Valgrind:未初始化的值是由堆分配创建的

转载 作者:行者123 更新时间:2023-12-04 15:36:46 25 4
gpt4 key购买 nike

更新:内存泄漏已被杀死,现在我需要知道如何初始化此语句:

vector *addorsub = (vector*)malloc(sizeof(*addorsub));

这是我从 valgrind 得到的:

gerasg@gerasg-iMac:~/Escritorio/valgrind/vg$ valgrind --tool=memcheck --leak-check=full --track-origins=yes ./eda.exe
==6129== Memcheck, a memory error detector
==6129== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==6129== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==6129== Command: ./eda.exe
==6129==
==6129== Conditional jump or move depends on uninitialised value(s)
==6129== at 0x4C2A7E4: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6129== by 0x4015E7: destroy_vector(vector*) (metbasicos.c:17)
==6129== by 0x4014E2: main (main.c:175)
==6129== Uninitialised value was created by a heap allocation
==6129== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6129== by 0x400D59: main (main.c:87)
==6129==
==6129==
==6129== HEAP SUMMARY:
==6129== in use at exit: 0 bytes in 0 blocks
==6129== total heap usage: 2 allocs, 2 frees, 16 bytes allocated
==6129==
==6129== All heap blocks were freed -- no leaks are possible
==6129==
==6129== For counts of detected and suppressed errors, rerun with: -v
==6129== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)

这是主程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "metbasicos.h"
#include "metintermedios.h"
#include "metavanzados.h"




//NumsVector, funcion que nos devuelve el numero de "numeros" que hay en cada vector del .txt,
//es decir, los n floats por cada vector

int NumsVector(char *linea, int size){
int numsvector = 1; //Inicializamos a 1 ya que no podemos suponer valor maximo segun enunciado, pero si minimo >= 1
int n;
for(n = 2; n<= size; n++){ //como ya suponemos que el primer valor despues del corchete es un numero y ya lo hemos contado, empezamos en 2
if (linea[n] != '[' && linea[n] != ']'){
if(linea[n] == 44){
numsvector = numsvector + 1;
}
}
}
return numsvector;
}

int main(){
int n =0, i = 0;
scanf("%d\n", &n);
vector **v = (vector **)malloc(sizeof(vector*) * n);
for(i = 0; i<n; ++i) {
char *line = NULL, ch;
int it = 0 ;
line = (char*) malloc (2*sizeof(char)) ;
*line = '\0' ;
while((ch=getchar()) != '\n')
{
*(line+it) = ch ;
it++ ;
line = (char*) realloc(line, (2*sizeof(char)) + it ) ;
}
*(line+it) = '\0';
int read = strlen(line);
int numsvector = NumsVector(line, read);
float* nfloat; //sabemos el tamanyo del vector que hemos leido, creamos array de floats y lo llenamos de los floats
//empieza el proceso para obtener los floats a partir de string de chars
nfloat = (float*)malloc(numsvector*sizeof(float));
int j = 0;
line[strlen(line)] = ','; /* Replaces the end ] with a , */
char *p = line + 1; /* creates a new pointer, pointing after the first [ in the original string */
do
{
sscanf(p, "%f,", &nfloat[j]); /* grabs up to the next comma as a float */
while (*(p++) != ',') ; /* moves pointer forward to next comma */
}
while (++j < numsvector); /* stops when you've got the expected number */
v[i] = create_vector(numsvector, nfloat);//conseguimos almacenar el contenido del string en un vector del tipo float (nfloat)
int aux;
for(aux = 0; aux<numsvector; ++aux){ //test de que cada elemento se ha guardado bien y printa todos los elementos ok
printf("V[%d]->data[%d] = : %.1f\n", i, aux, v[i]->data[aux]); //test de que la memoria se almacena bien, luego se borra
}
free(line);
free(nfloat);
}
char mystring [21];
char str[10], charv1[6], charv2[6];
int operation = 0;
char simbol[4]; /* Can be +, - and dot */
mystring[0] = str[0] = charv1[0] = charv2[0] = simbol[0] = 'a';
for(i = 0; i<21; i++){
mystring[i] = 'a';
}
for(i = 0; i<6; i++)
{
charv1[i] = 'a';
charv2[i] = 'a';
}
for (i = 0; i < 10; i++)
{
str[i] = 'a';
}
for (i = 0; i < 4; i++)
{
simbol[i] = 'a';
}
vector *addorsub = (vector*)malloc(sizeof(*addorsub));
fgets (mystring , 21 , stdin);
do {
sscanf (mystring,"%s",str);
int res = strlen (str);
//int res = strncmp(str, "incr", 10);
if(mystring[0] == 'p') operation = 1;
else if(mystring[0] == 'i') operation = 2;
else if(mystring[0] == 'd' && mystring[1] == 'i') operation = 4;
else if(mystring[0] == 'd' && mystring[1] == 'e') operation = 5;
else if(res == 9) operation = 6;
else if(res == 4 && mystring[0] == 'n') operation = 7;
else{
sscanf (mystring,"%s %s",str, simbol);
if (simbol[0] == '+') operation = 8;
else if(simbol[0] == '-') operation = 9;
else operation = 3;
}
int v1 = 0, v2 = 0;
float returnresult = 0.0;
switch(operation)
{
case 1 :
sscanf (mystring,"%s %s",str, charv1);
v1 = strtol((charv1+1) , NULL , 10);
printf("PRINT: %d\n", v1);
print(v[v1-1]);
break;
case 2 :
sscanf (mystring,"%s %s %s",str, charv1, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
printf("INCREASE: %d %d\n", v1, v2);
incr(v[v1-1], v[v2-1]);
break;
case 3 :
sscanf (mystring,"%s %s %s",charv1, str, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
returnresult = dot(v[v1-1], v[v2-1]);
printf("DOT: %d %d\n", v1, v2);
printf("%f\n", returnresult);
break;
case 4 :
sscanf (mystring,"%s %s %s", str, charv1, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
returnresult = distance(v[v1-1], v[v2-1]);
printf("%f\n", returnresult);
break;
case 5 :
sscanf (mystring,"%s %s %s",str, charv1, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
decr(v[v1-1], v[v2-1]);
break;
case 6 :
sscanf (mystring,"%s %s",str, charv1);
v1 = strtol((charv1+1) , NULL , 10);
normalize(v[v1-1]);
break;
case 7 :
sscanf (mystring,"%s %s",str, charv1);
v1 = strtol((charv1+1) , NULL , 10);
returnresult = norm(v[v1-1]);
printf("%f\n", returnresult);
break;
case 8 : //suma
sscanf (mystring,"%s %s %s", charv1, str, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
addorsub = add(v[v1-1], v[v2-1]);
printf("SUMA: %d %d\n", v1, v2);
print(addorsub);
break;
case 9 :
sscanf (mystring,"%s %s %s", charv1, str, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
addorsub = sub(v[v1-1], v[v2-1]);
printf("resta: %d %d\n", v1, v2);
print(addorsub);
break;
default :
printf("operation value is: %d\n", operation);
break;
}
operation = 0;
} while (fgets (mystring , 21 , stdin) != NULL);
for (i = 0; i < n; ++i)
{
destroy_vector(v[i]);
}
free(v);
}

我检查了所有的 malloc 和 frees,但我想我要留下任何东西......

有什么想法吗?非常感谢。

编辑:

输入示例(将 .txt 文件作为标准输入):

3
[9.3,1.2,87.9]
[1.0,1.0]
[0.0,0.0,1.0]
v1 + v2
v3 - v1
incr v3 v1
decr v1 v3
decr v1 v3
v2 dot v3
norm v3
distance v1 v3
normalize v3
print v3

结构:

typedef struct {
float* data;
int size;
} vector;

metbasicos.c:

#include "metbasicos.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/* Metodos Básicos */
vector *create_vector(int n, float* data){
vector *newvect = (vector*)malloc(sizeof(*newvect));
newvect->data = (float*)malloc(n*sizeof(float));
memcpy(newvect->data, data, sizeof(float) * n);
newvect->size = n;
return newvect;
}

void destroy_vector(vector* v){
free(v->data);
free(v);
}

void print(vector* v){
int size = v->size, i;
for (i = 0; i < size; ++i)
{
if(i == 0) printf("[%.1f,", v->data[i]);
else if(i == (size-1)) printf("%.1f]\n", v->data[i]);
else printf("%.1f,", v->data[i]);
}
}

metintermedios.c:

#include "metintermedios.h"
#include "metbasicos.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/* Metodos Intermedios */
float dotDiferentSizes(vector* v1, vector* v2, int smax, int smin){
float prod = 0.0;
int i;
for(i = 0; i < smin; i++){
prod = prod + (v1->data[i])*(v2->data[i]); // += means add to product
}
for(i = smin; i < smax; i++){
prod += (v1->data[i])*0; // += means add to product
}
return prod;
}

float dot(vector* v1, vector* v2){
int smax = (v1->size), smin = 0;
int v1size = smax;
int v2size = (v2->size);
float product = 0.0;
if (v2size > smax) {
smax = v2size; //max_size checking
smin = v1size; //min_size checking
}
else if (v2size < smax){
smin = v2->size;
}
else {
if(v1size == v2size){
smin = smax;
}
}
// compute
if(smax == smin){
int i;
for(i = 0; i < smin; i++){
product += (v1->data[i])*(v2->data[i]); // += means add to product
}
}
else{
if(v1size == smax && v1size!= smin){
product = dotDiferentSizes(v1,v2,smax,smin); //v1>v2
}
if(v2size == smax && v2size!= smin){
product = dotDiferentSizes(v2,v1,smax,smin); //v2>v1 OJU nomes canviem l'ordre en que posem els parametres, la funcio es identica.
}
}
return product;
}

float norm(vector* v){
int size = v->size, i;
float norm = 0.0;
for(i= 0; i < size; i++){
norm += (v->data[i])*(v->data[i]);
}
norm = sqrt( norm );
return norm;
}

void normalize(vector* v){
int size = v->size, i;
float norma = 0.0;
norma = norm(v);
for(i= 0; i< size; i++){
v->data[i] = v->data[i] / norma;
}
print(v);
}

metavanzados.c:

#include "metavanzados.h"
#include "metintermedios.h"
#include "metbasicos.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/* Metodos Avanzados */
vector* add(vector* v1, vector* v2){
vector *vadd = (vector*)malloc(sizeof(*vadd));
int v1size, v2size, i;
v1size = v1->size;
int size = v1size;
v2size = v2->size;
if(v2size > v1size) {
size = v2size;
vadd = create_vector(size, v2->data);
for(i = 0; i < v1size; i++){
vadd->data[i] += v1->data[i];
}
}
else {
vadd = create_vector(size, v1->data);
for(i = 0; i < v1size; i++){
vadd->data[i] += v2->data[i];
}
}
return(vadd);
destroy_vector(vadd);
}

vector* sub(vector* v1, vector* v2){
vector *vsub = (vector*)malloc(sizeof(*vsub));
int v1size, v2size, i;
v1size = v1->size;
int size = v1size;
v2size = v2->size;
if(v2size > v1size) {
size = v2size;
vsub = create_vector(size, v2->data);
for(i = 0; i < v1size; i++){
vsub->data[i] = v1->data[i] - vsub->data[i]; /* restamos siempre v1 - v2*/
} /* en el bucle forzamos a restar v1 - v2, evitando el caso v2 - v1*/
for(i = v1size; i < size; i++){
vsub->data[i] = (v2->data[i])*(-1);
}
}
else { /* v1size >= v2size */
vsub = create_vector(size, v1->data);
for(i = 0; i < v2size; i++){
vsub->data[i] -= v2->data[i];
}
}
return(vsub);
destroy_vector(vsub);
}

void incr(vector* source, vector* other){
int smax, i, ssize = source->size, osize = other->size;
vector *vincr = (vector*)malloc(sizeof(*vincr));
if(ssize > osize) smax = ssize;
else {
if(ssize < osize) smax = osize;
else smax = ssize;
}
vincr = add(source, other);
if(ssize > osize){
for(i = 0; i < smax; i++){
source->data[i] = vincr->data[i];
}
}
else{
source->data = (float*)realloc(source->data, sizeof(float) * smax);
source->size = smax;
for(i = 0; i < smax; i++){
source->data[i] = vincr->data[i];
}
}
print(source);
destroy_vector(vincr);
}

void decr(vector* source, vector* other){
int smax, i, ssize = source->size, osize = other->size;
if(ssize > osize) smax = ssize;
else {
if(ssize < osize) smax = osize;
else smax = ssize;
}
vector *vdecr = (vector*)malloc(sizeof(*vdecr));
vdecr = sub(source, other);
if(ssize > osize){
for(i = 0; i < smax; i++){
source->data[i] = vdecr->data[i];
}
}
else{
source->data = (float*)realloc(source->data, sizeof(float) * smax);
source->size = smax;
for(i = 0; i < smax; i++){
source->data[i] = vdecr->data[i];
}
}
print(source);
destroy_vector(vdecr);
}

float distance(vector* v1, vector* v2){
int i;
float dist = 0.0;
vector *vdist = (vector*)malloc(sizeof(*vdist));
vdist = sub(v1, v2);
for(i = 0; i<= vdist->size; i++){
vdist->data[i] = (vdist->data[i])*(vdist->data[i]);
dist += vdist->data[i];
}
dist = sqrt( dist );
return dist;
destroy_vector(vdist);
}

这是所有代码。

最佳答案

    case 8 : //suma
sscanf (mystring,"%s %s %s", charv1, str, charv2);
v1 = strtol((charv1+1) , NULL , 10);
v2 = strtol((charv2+1) , NULL , 10);
addorsub = add(v[v1-1], v[v2-1]);
printf("SUMA: %d %d\n", v1, v2);
print(addorsub);
break;

这是你的问题。指针 addorsub 已经进行了 malloc 处理,但是 add() 函数返回了一个进行了 malloc 处理的 vector 指针。所以 add() 函数内部的 vadd vector 指针正在覆盖 addorsub 指针,这使得已经在 addorsub 指针中分配的内存......消失得无影无踪。

sub() 函数也会发生同样的事情。在 return 语句之后实际上不可能销毁分配的内存,因此您必须在调用 add() 或 sub() 函数之前销毁指针中的内存,然后再调用这些函数以保留内存。

所以在 main() 函数、incr() 函数、decr() 函数等中,你需要为任何接收到 add() 或 sub() 指针的东西取出内存分配,如以及确保在将指针重新分配给不同地址之前销毁当前分配的任何内存是否在循环内部。

UPDATE: Memory leaks killed, now I need to know how can I initialize this statement:

   vector *addorsub = (vector*)malloc(sizeof(*addorsub));

你不会的。做吧

    vector * addorsub = NULL;

并确保 addorsub 在循环的每次迭代中都能调用 free()。

关于c - Valgrind:未初始化的值是由堆分配创建的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19482084/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com