una tipos servicio segmento segmentacion mercado empresa ejemplo demografica clientes caracteristicas c segmentation-fault

servicio - tipos de segmentacion de clientes



falla de segmentación: 11 (4)

Tengo un problema con algún programa, he buscado fallas de segmentación porque no las entiendo bastante bien, lo único que sé es que, presumiblemente, estoy tratando de acceder a algún tipo de memoria que no debería. El problema es que veo mi código y no entiendo lo que estoy haciendo mal.

#include<stdio.h> #include<math.h> #include<stdlib.h> #define lambda 2.0 #define g 1.0 #define Lx 100 #define F0 1.0 #define Tf 10 #define h 0.1 #define e 0.00001 FILE *file; double F[1000][1000000]; void Inicio(double D[1000][1000000]) { int i; for (i=399; i<600; i++) { D[i][0]=F0; } } void Iteration (double A[1000][1000000]) { long int i,k; for (i=1; i<1000000; i++) { A[0][i]= A[0][i-1] + e/(h*h*h*h)*g*g*(A[2][i-1] - 4.0*A[1][i-1] + 6.0*A[0][i-1]-4.0*A[998][i-1] + A[997][i-1]) + 2.0*g*e/(h*h)*(A[1][i-1] - 2*A[0][i-1] + A[998][i-1]) + e*A[0][i-1]*(lambda-A[0][i-1]*A[0][i-1]); A[1][i]= A[1][i-1] + e/(h*h*h*h)*g*g*(A[3][i-1] - 4.0*A[2][i-1] + 6.0*A[1][i-1]-4.0*A[0][i-1] + A[998][i-1]) + 2.0*g*e/(h*h)*(A[2][i-1] - 2*A[1][i-1] + A[0][i-1]) + e*A[1][i-1]*(lambda-A[1][i-1]*A[1][i-1]); for (k=2; k<997; k++) { A[k][i]= A[k][i-1] + e/(h*h*h*h)*g*g*(A[k+2][i-1] - 4.0*A[k+1][i-1] + 6.0*A[k][i-1]-4.0*A[k-1][i-1] + A[k-2][i-1]) + 2.0*g*e/(h*h)*(A[k+1][i-1] - 2*A[k][i-1] + A[k-1][i-1]) + e*A[k][i-1]*(lambda-A[k][i-1]*A[k][i-1]); } A[997][i] = A[997][i-1] + e/(h*h*h*h)*g*g*(A[0][i-1] - 4*A[998][i-1] + 6*A[997][i-1] - 4*A[996][i-1] + A[995][i-1]) + 2.0*g*e/(h*h)*(A[998][i-1] - 2*A[997][i-1] + A[996][i-1]) + e*A[997][i-1]*(lambda-A[997][i-1]*A[997][i-1]); A[998][i] = A[998][i-1] + e/(h*h*h*h)*g*g*(A[1][i-1] - 4*A[0][i-1] + 6*A[998][i-1] - 4*A[997][i-1] + A[996][i-1]) + 2.0*g*e/(h*h)*(A[0][i-1] - 2*A[998][i-1] + A[997][i-1]) + e*A[998][i-1]*(lambda-A[998][i-1]*A[998][i-1]); A[999][i]=A[0][i]; } } main() { long int i,j; Inicio(F); Iteration(F); file = fopen("P1.txt","wt"); for (i=0; i<1000000; i++) { for (j=0; j<1000; j++) { fprintf(file,"%lf /t %.4f /t %lf/n", 1.0*j/10.0, 1.0*i, F[j][i]); } } fclose(file); }

Gracias por tu tiempo.


¿En qué sistema estás corriendo? ¿Tiene acceso a algún tipo de depurador (gdb, depurador de Visual Studio, etc.)?

Eso nos daría información valiosa, como la línea de código donde el programa se bloquea ... Además, la cantidad de memoria puede ser prohibitiva.

Además, ¿puedo recomendarle que reemplace los límites numéricos por definiciones con nombre?

Como tal:

#define DIM1_SZ 1000 #define DIM2_SZ 1000000

Úselos cuando quiera referirse a los límites de dimensión de la matriz. Ayudará a evitar errores de tipeo.


Ejecute su programa con valgrind de vinculado a efence . Eso le dirá dónde se está desreferenciando el puntero y probablemente solucionará su problema si soluciona todos los errores de los que le informan.


Esta declaración:

double F[1000][1000000];

ocuparía 8 * 1000 * 1000000 bytes en un sistema típico x86. Esto es aproximadamente 7,45 GB. Lo más probable es que su sistema se esté quedando sin memoria cuando intente ejecutar su código, lo que genera un error de segmentación.


Su matriz ocupa aproximadamente 8 GB de memoria (1,000 x 1,000,000 x sizeof (doble) bytes). Eso podría ser un factor en tu problema. Es una variable global en lugar de una variable de pila, por lo que puede estar bien, pero aquí se están limitando los límites.

Escribir esa cantidad de datos en un archivo tomará un tiempo.

No comprueba si el archivo se abrió correctamente, lo que también podría ser un problema (si falla, es muy probable que se produzca un error de segmentación).

Deberías introducir algunas constantes con nombre para 1,000 y 1,000,000; ¿Qué representan?

También debe escribir una función para hacer el cálculo; podría usar una función en inline en C99 o posterior (o C ++). La repetición en el código es insoportable de contemplar.

También debe usar la notación C99 para main() , con el tipo de retorno explícito (y preferiblemente void para la lista de argumentos cuando no esté usando argc o argv ):

int main(void)

Por curiosidad, tomé una copia de tu código, cambié todas las ocurrencias de 1000 a ROWS, todas las ocurrencias de 1000000 a COLS, y luego creé enum { ROWS = 1000, COLS = 10000 }; (reduciendo así el tamaño del problema por un factor de 100). Hice algunos cambios menores para que se compilara limpiamente en mi conjunto preferido de opciones de compilación (nada serio: static frente a las funciones, y la matriz principal; el file convierte en un local a main ; el error comprueba el fopen() , etc. )

Luego creé una segunda copia y creé una función en línea para hacer el cálculo repetido (y una segunda para hacer cálculos de subíndice). Esto significa que la expresión monstruosa solo se escribe una vez, lo que es muy deseable ya que garantiza la coherencia.

#include <stdio.h> #define lambda 2.0 #define g 1.0 #define F0 1.0 #define h 0.1 #define e 0.00001 enum { ROWS = 1000, COLS = 10000 }; static double F[ROWS][COLS]; static void Inicio(double D[ROWS][COLS]) { for (int i = 399; i < 600; i++) // Magic numbers!! D[i][0] = F0; } enum { R = ROWS - 1 }; static inline int ko(int k, int n) { int rv = k + n; if (rv >= R) rv -= R; else if (rv < 0) rv += R; return(rv); } static inline void calculate_value(int i, int k, double A[ROWS][COLS]) { int ks2 = ko(k, -2); int ks1 = ko(k, -1); int kp1 = ko(k, +1); int kp2 = ko(k, +2); A[k][i] = A[k][i-1] + e/(h*h*h*h) * g*g * (A[kp2][i-1] - 4.0*A[kp1][i-1] + 6.0*A[k][i-1] - 4.0*A[ks1][i-1] + A[ks2][i-1]) + 2.0*g*e/(h*h) * (A[kp1][i-1] - 2*A[k][i-1] + A[ks1][i-1]) + e * A[k][i-1] * (lambda - A[k][i-1] * A[k][i-1]); } static void Iteration(double A[ROWS][COLS]) { for (int i = 1; i < COLS; i++) { for (int k = 0; k < R; k++) calculate_value(i, k, A); A[999][i] = A[0][i]; } } int main(void) { FILE *file = fopen("P2.txt","wt"); if (file == 0) return(1); Inicio(F); Iteration(F); for (int i = 0; i < COLS; i++) { for (int j = 0; j < ROWS; j++) { fprintf(file,"%lf /t %.4f /t %lf/n", 1.0*j/10.0, 1.0*i, F[j][i]); } } fclose(file); return(0); }

Este programa escribe en P2.txt lugar de P1.txt . Ejecuté ambos programas y comparé los archivos de salida; la salida fue idéntica. Cuando ejecuté los programas en una máquina en su mayoría inactiva (MacBook Pro, Intel Core i7 a 2.3 GHz, 16 GiB 1333 MHz RAM, Mac OS X 10.7.5, GCC 4.7.1), obtuve un tiempo razonable pero no del todo consistente:

Original Modified 6.334s 6.367s 6.241s 6.231s 6.315s 10.778s 6.378s 6.320s 6.388s 6.293s 6.285s 6.268s 6.387s 10.954s 6.377s 6.227s 8.888s 6.347s 6.304s 6.286s 6.258s 10.302s 6.975s 6.260s 6.663s 6.847s 6.359s 6.313s 6.344s 6.335s 7.762s 6.533s 6.310s 9.418s 8.972s 6.370s 6.383s 6.357s

Sin embargo, casi todo ese tiempo se gasta en E / S de disco. Reduje la E / S de disco a solo la última fila de datos, por lo que la E / S externa for bucle se convirtió en:

for (int i = COLS - 1; i < COLS; i++)

los tiempos fueron muy reducidos y mucho más consistentes:

Original Modified 0.168s 0.165s 0.145s 0.165s 0.165s 0.166s 0.164s 0.163s 0.151s 0.151s 0.148s 0.153s 0.152s 0.171s 0.165s 0.165s 0.173s 0.176s 0.171s 0.165s 0.151s 0.169s

La simplificación en el código de tener la expresión espantosa escrita una sola vez es muy beneficiosa, me parece a mí. Definitivamente tendré que mantener ese programa mucho mejor que el original.