分段故障(堆芯转储) 我尝试在C++中实现KMead算法,问题是当我在尝试实现一个函数来初始化方法时…它给了我这个错误,我搜索了这么多,看看我是否超过了数组大小的数量,但事情看起来不错,没有溢出存在。代码如下: 头文件:

分段故障(堆芯转储) 我尝试在C++中实现KMead算法,问题是当我在尝试实现一个函数来初始化方法时…它给了我这个错误,我搜索了这么多,看看我是否超过了数组大小的数量,但事情看起来不错,没有溢出存在。代码如下: 头文件:,c++,pointers,multidimensional-array,scanf,C++,Pointers,Multidimensional Array,Scanf,您正在将“v”传递到initMeans函数并在那里初始化它。但是,分配给v的值不会传播回函数。我要么修改函数以返回v,要么在调用函数之前分配v。我也有同样的问题。当我调用一个返回整数的函数时,我遇到了分段错误。 后来我想,我犯了一个非常简单的错误。 在创建类的对象时,我编写了以下内容- 对象*对象; 而不是对象*对象=新对象() 希望这个答案有帮助。 谢谢 Shraddha使用g++-Wall-Wextra-g km.cpp main.cpp-o km编译,然后使用调试器gdb km(也可能)。

您正在将“v”传递到initMeans函数并在那里初始化它。但是,分配给v的值不会传播回函数。我要么修改函数以返回v,要么在调用函数之前分配v。

我也有同样的问题。当我调用一个返回整数的函数时,我遇到了分段错误。 后来我想,我犯了一个非常简单的错误。 在创建类的对象时,我编写了以下内容-

对象*对象; 而不是对象*对象=新对象()

希望这个答案有帮助。 谢谢
Shraddha

使用
g++-Wall-Wextra-g km.cpp main.cpp-o km
编译,然后使用调试器
gdb km
(也可能)。改进您的代码,直到您没有收到任何警告(因此不要忽略
fscanf
!)的结果作为旁注,考虑到您正在做的事情,您可能希望生成比
rand()
更好的随机数。如果您有可用的c++11,那么在标准库中就有更好的随机数生成。此外,您也可以使用来自C++库的STD::数组,这可能会帮助您与内存相关的问题。BTW,您的代码不是真正的C++;使用
我无法立即看到直接原因,但问题的根本原因是使用了固定大小的数组和原始指针。使用
std::string
std::vector
和C++风格的IO:代码的大小将是C++的一半,并且更不容易出错。
我正在尝试用C++实现kmeans算法。
如果您要实现一个算法,我还建议您停止使用指针,使用容器类,例如
std::string
std::vector
,等等。如果你这样做了,你将花时间实现你的算法,而不是与指针、动态分配等斗争。效果先生,我照你说的做了,分割错误消失了,但警告仍然出现。fsacnf()中有错误吗?可以在cpp文件中使用c指令吗?!我通过调用n=fscanf(f、%d、&n)修复了警告:我很高兴这有帮助。我在上面的回答指出了现有代码中的问题,并对其进行了最小的修改。然而,对于“生产”代码,我实际上使用了它,而不是像上面的海报所指出的那样使用原始指针。
#ifndef KM_HPP
#define KM_HPP
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define HIGH_VALUE 50

// fonction d'initialisation
void initMeans(float **, double **, int , int , int );
#endif
#include "km.hpp"

// fonction d'initialisation
void initMeans(float **x, double **v, int n, int p, int c){
    srand(time(0));
    for(int i=0; i<n; i++) x[i][p] = rand()%c;
    v = new double*[c];
    for(int i=0; i<c; i++) v[i] = new double[p];
    for(int i = 0; i < c; i++) for(int j = 0; j < p; j++){
    double num = 0; int denum = 0;
    for(int k = 0; k < n; k++) if(x[k][p] == i){
    num += x[k][j]; denum++;
    }
    v[i][j] = num/denum;
    }
}
#include "km.hpp"

using namespace std;
//Les variables globale :

char nomExt[40];
int n, p, c;
float **x;
double **v;
FILE *f;

int main(){
    cout<<" donnée le nom de la fichier data :";
    cin>>nomExt;
    f=fopen(nomExt,"r");
    fscanf(f,"%d",&n);
    fscanf(f,"%d",&p);
    fscanf(f,"%d",&c);

    x = new float*[n];
    for(int i=0;i<n;i++) x[i]= new float[p];

    for(int i=0;i<n;i++){
        for(int j=0;j<p;j++) fscanf(f,"%f",&x[i][j]);
    }

    initMeans(x, v, n, p, c);
    for(int i=0;i<c;i++){
        for(int j=0;j<p;j++) cout<<v[i][j]<<"\t";
        cout<<endl;
    }   
    for(int j=0;j<p;j++) delete [] x[j];

    delete [] x; 
    for(int j=0;j<p;j++) delete [] v[j];

    delete [] v;
        fclose(f);
    return 0;
}
g++ -o km -O3 km.cpp main.cpp
main.cpp: In function ‘int main()’:
main.cpp:16:19: warning: ignoring return value of ‘int fscanf(FILE*, const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
  fscanf(f,"%d",&n);
                   ^
main.cpp:17:19: warning: ignoring return value of ‘int fscanf(FILE*, const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
  fscanf(f,"%d",&p);
                   ^
main.cpp:18:19: warning: ignoring return value of ‘int fscanf(FILE*, const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
  fscanf(f,"%d",&c);
                   ^
main.cpp:24:47: warning: ignoring return value of ‘int fscanf(FILE*, const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
   for(int j=0;j<p;j++) fscanf(f,"%f",&x[i][j]);
Erreur de segmentation (core dumped) ==> [Segmentation fault (core dumped)]