Fallo de segmentación con matrices intrínsecas
Sigo recibiendo errores de segmentación con el siguiente código cada vez que intento escribir en “result”. El propósito del código es convertir una matriz de dobles “data” en un arreglo de __m256d, agregando buffers de columnas de 0’s si es necesario mientras se transpone simultáneamente. Ejemplo:
[[0, 1, 2, 3, 4, 5]
[6, 7, 8, 9, 10, 11]]
se transpone a
[{0, 1, 2, 3}, {6, 7, 8, 9},
{4, 5, 0, 0}, {10, 11, 0, 0}]
La función es la siguiente:
void transpose<em>alter(<strong>m256d *result, matrix *mat) {
for (int r = 0; r < mat->rows; r++) {
double *mat</strong></em>data<em>offset = (double *) mat->data + r * mat->cols;
int c</em>block;
for (c<em>block = 0; c</em>block < mat->cols / 4; c<em>block++) {
result[c</em>block * mat->rows + r] = <em>mm256</em>loadu<em>pd(mat</em>data<em>offset + c</em>block * 4);
}
if (mat->cols % 4 > 0) {
double buffer[4] = {0, 0, 0, 0};
memcpy(buffer, mat<em>data</em>offset + c<em>block * 4, (mat->cols % 4) * sizeof(double));
result[c</em>block * mat->rows + r] = <em>mm256</em>loadu<em>pd(buffer);
}
}
}
El argumento pasado en “result” cuando se producen errores de segmentación es:
_</em>m256d *alt = (m256d *) malloc((mat->cols + 3) / 4 * mat->rows * sizeof(__m256d));
davy.ai
El segfault probablemente está ocurriendo porque se está accediendo al array
result
fuera de los límites. Específicamente, la memoria asignada pararesult
puede que no sea lo suficientemente grande como para contener todos los elementos que se están escribiendo en ella.En el código proporcionado,
result
se asigna utilizandomalloc
con un tamaño de(mat->cols + 3) / 4 * mat->rows * sizeof(__m256d)
. La expresión(mat->cols + 3) / 4
calcula el número de bloques de 4 elementos necesarios para contener todas las columnas de la matriz. Sin embargo, esta expresión no tiene en cuenta la posibilidad de necesitar un bloque extra para contener cualquier columna restante que no encaje uniformemente en bloques de 4 elementos.Para solucionar el problema, el tamaño de
result
debe calcularse de la siguiente manera:Este código calcula el número de bloques de 4 elementos necesarios como antes, pero también comprueba si hay columnas restantes que no encajan uniformemente en bloques (
num_extra_cols
). Si las hay, incrementa el número de bloques necesarios.Con este cambio,
result
debería ser lo suficientemente grande como para contener todos los elementos que se están escribiendo en ella, y el segfault debería resolverse.